1. 线程创建
功能: 创建一个新的线程。
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
参数说明:
thread:返回线程 ID。attr:设置线程属性,为 NULL 表示使用默认属性。start_routine:线程启动后要执行的函数地址。arg:传给线程启动函数的参数。
返回值: 成功返回 0;失败返回错误码。
错误检查: Pthreads 函数出错时不会设置全局变量 errno,而是将错误代码通过返回值返回。建议通过返回值判定错误,因为读取返回值比读取线程内的 errno 变量开销更小。
线程 ID 及进程地址空间布局: pthread_create 函数产生的线程 ID 存放在第一个参数指向的地址中。该 ID 属于 NPTL 线程库范畴,用于后续操作线程。NPTL 提供了 pthread_self 函数获取线程自身 ID:
pthread_t pthread_self(void);
2. 线程等待
新线程的创建后,主进程需要等待,否则会出现类似僵尸进程的问题。
pthread_join 接口:
- 返回值:成功为 0,失败返回错误码。
- 第一个参数:指定要等待的线程 ID。
- 第二个参数:二级指针,若不需要获取返回值可设为 nullptr。
- 行为:默认阻塞等待。
获取线程返回值: 线程退出时的返回值类型为 void*,存储在系统资源中。用户需定义一个 void* 变量,将其地址传入 pthread_join 的第二个参数。当线程退出时,会将返回值传给该指针指向的内存区域。
异常处理: 线程一旦异常,整个进程会挂掉,其他线程也会受影响。因此 pthread_join 不考虑线程异常,只需主进程考虑进程层面的异常即可。
3. 线程终止 (退出)
在进程中可使用 return 和 exit 退出,但在线程中直接调用 exit 会导致整个进程挂掉。线程可通过以下方式终止:
return:从线程函数返回。pthread_exit(void *retval):显式终止当前线程并传递返回值。pthread_cancel(pthread_t tid):主进程可关闭某个已存在的线程,此时等待返回值变为 PTHREAD_CANCELED。
4. 原生线程库
Linux 中的 pthread 库是原生线程库。C++11 虽然支持多线程,但在 g++ 编译时仍需加 -lpthread 选项,底层仍依赖 Linux 原生线程库。
4.1 重新理解原生线程库
Linux 中没有独立的线程概念,只有轻量级进程(LWP)。创建轻量级进程需调用 clone 系统接口。


