【APUE】线程控制
在UNIX系统中,线程提供了分解并发任务的另一种模型
线程终止
单个线程可以通过3种方式退出:
- 简单的从单个启动例程中返回,返回值是线程的退出码
- 线程可以被同一进程中的其他线程取消 int pthread_cancel(pthread_t tid)
- 线程调用pthread_exit分配在栈上的变量作为pthread_exit的参数时,其他线程在使用该变量的时候栈上的内容可能已经被更改或撤销,导致程序报错或者访问到错误的数据
#include <pthread.h> void pthread_exit(void *rval_ptr); void pthread_join(pthread_t thread, void **rval_ptr) // 访问线程返回的指针
线程同步
为了保证每个线程看到一致的数据视图,需要使用互斥量来保证同一时间只有一个线程访问数据
当一个以上的线程需要访问动态分配的对象时,可以在对象中嵌入引用计数
避免死锁
- 使所有的线程都以相同的顺序加锁
- 当程序结构复杂时,对互斥量排序比较困难,就需要先释放占有的锁,过一段时间再试
读写锁
三种状态
- 读模式加锁;写模式加锁;不加锁
当读写锁时写加锁状态时,所有试图对这个锁加锁的线程都会被阻塞;当读模式加锁状态时,所有读模式加锁都可以得到访问权,但是写模式加锁的线程都会阻塞;当有线程试图进行写模式加锁时,之后所有的读模式加锁都会被阻塞。
自旋锁
在获取锁之前一直处于忙等阻塞的状态,适用于:锁被持有的时间短,线程不希望在重新调度上花费太多的成本;在非抢占式内核中非常有用,在用户程序中并不是非常有用
屏障(barrier)
允许某个线程等待,直到所有的合作线程都到达某一点(所有等待的线程都完成工作),然乎从该点继续执行;
线程控制
- 一个进程可以创建的最大线程数没有确定的限制,但并不是说没有限制;
- 互斥量属性控制同一线程是否可以对一个互斥量多次加锁
重入
在多任务环境中,一个函数可以在任何时刻中断它,转入OS调度下去执行另外一段代码,而返回控制时不会出现任何错误;
线程安全
- 如果要一个函数在同一时间点可以被多个线程安全的调用,称该函数是线程安全的
- 如果一个函数对多个线程来说是可重入的,就说这个函数是线程安全的
线程特定数据(线程私有数据)
查询或存储某个特定线程相关数据的一种机制,,防止某个线程数据于其他线程数据混淆,提供了让基于进程的接口适应多线程环境的机制
线程和信号
一个进程中的信号处理是所有线程共享的
线程和fork
子进程和父进程都没有对内存内容作出改动时,子进程和父进程共享内存页的副本
线程和I/O
进程中所有线程共享文件描述符,文件读取可以使用原子操作