【APUE】线程控制

在UNIX系统中,线程提供了分解并发任务的另一种模型

线程终止

单个线程可以通过3种方式退出:

  • 简单的从单个启动例程中返回,返回值是线程的退出码
  • 线程可以被同一进程中的其他线程取消 int pthread_cancel(pthread_t tid)
  • 线程调用pthread_exit
    #include <pthread.h>
    void pthread_exit(void *rval_ptr);
    void pthread_join(pthread_t thread, void **rval_ptr)  // 访问线程返回的指针
    
    分配在栈上的变量作为pthread_exit的参数时,其他线程在使用该变量的时候栈上的内容可能已经被更改或撤销,导致程序报错或者访问到错误的数据

线程同步

为了保证每个线程看到一致的数据视图,需要使用互斥量来保证同一时间只有一个线程访问数据

当一个以上的线程需要访问动态分配的对象时,可以在对象中嵌入引用计数

避免死锁

  • 使所有的线程都以相同的顺序加锁
  • 当程序结构复杂时,对互斥量排序比较困难,就需要先释放占有的锁,过一段时间再试

读写锁

三种状态

  • 读模式加锁;写模式加锁;不加锁

当读写锁时写加锁状态时,所有试图对这个锁加锁的线程都会被阻塞;当读模式加锁状态时,所有读模式加锁都可以得到访问权,但是写模式加锁的线程都会阻塞;当有线程试图进行写模式加锁时,之后所有的读模式加锁都会被阻塞。

自旋锁

在获取锁之前一直处于忙等阻塞的状态,适用于:锁被持有的时间短,线程不希望在重新调度上花费太多的成本;在非抢占式内核中非常有用,在用户程序中并不是非常有用

屏障(barrier)

允许某个线程等待,直到所有的合作线程都到达某一点(所有等待的线程都完成工作),然乎从该点继续执行;

线程控制

  • 一个进程可以创建的最大线程数没有确定的限制,但并不是说没有限制;
  • 互斥量属性控制同一线程是否可以对一个互斥量多次加锁

重入

在多任务环境中,一个函数可以在任何时刻中断它,转入OS调度下去执行另外一段代码,而返回控制时不会出现任何错误;

线程安全

  • 如果要一个函数在同一时间点可以被多个线程安全的调用,称该函数是线程安全的
  • 如果一个函数对多个线程来说是可重入的,就说这个函数是线程安全的

线程特定数据(线程私有数据)

查询或存储某个特定线程相关数据的一种机制,,防止某个线程数据于其他线程数据混淆,提供了让基于进程的接口适应多线程环境的机制

线程和信号

一个进程中的信号处理是所有线程共享的

线程和fork

子进程和父进程都没有对内存内容作出改动时,子进程和父进程共享内存页的副本

线程和I/O

进程中所有线程共享文件描述符,文件读取可以使用原子操作