Linux 中的线程本质
线程接口由 Native POSIX Thread Library 提供,即:NPTL 库函数
线程被称为轻量级进程 (Light Weight Process)
每一个线程在内核中都对应一个调度实体,拥有独立的结构体 (task_struct)
- 内核设计:一个进程对应内核中的一个结构体,对应一个进程标识
- 引入线程:线程是内核的调度实体,在内核中必然对应一个结构体
用户模式:一个进程中存在多个线程
内核模式:每个线程是一个独立的调度实体
另一个视角
拥有多线程的进程,又被称为线程组 (谁是线程组长?)
在内核数据结构 task_struct 中存在 pid 和 tgid:
pid_t pid => 线程标识符 (Thread ID)
pid_t tgid => 线程组标识符 (Thread Group ID)
进程创建后默认拥有一个线程,即:主线程 (默认执行流)
主线程的 LWP 标识与进程标识符相同,即:主线程为线程组长
其他子线程创建后隶属于当前进程:
- 子线程的 LWP 标识符各不相同,且与进程标识符相同
- 子线程调用 getpid() 的结果相同 (why?)
下面的程序输出什么?为什么?
问题
对于线程来说,pthread_t 类型的标识符 与 pid_t 类型标识有什么不同?
使用 ps 命令查看线程信息
-e => Select all processes
-L => Show threads,possibly with LWP and NLWP columns
-f => Do full-format listing
ps -eLf => to get info about threads
实验程序
多线程内核模型
Linux 内核中的基本调度单位为 task_struct,即:内核中以 "任务" 作为调度的基本单位
值得思考的问题
多线程之间是否有 "父子关系" ?
答:无!
进程中只有主线程和子线程,线程之间没有 "父子关系"
主线程如果先于子线程结束会发生什么?
Linux 中主线程如果执行结束,则进程结束
进程结束则进程资源被释放,子线程被迫结束
使用 kill 命令是否能够 "杀死" 指定线程 ?
kill 命令默认发送信号 SIGTERM,而信号的目标是进程
因此,kill 任意子线程的 pid_t 将导致整个进程结束
pthread_t 究竟是什么数据类型 ?
pthread_t 是 POSIX Thread 中的接口,具体定义与系统相关
通常情况下,pthread_t 的具体定义是 一个整型值
- Linux 中 pthread_t 的具体定义是 64 位整数 (保存地址值)
- 其他系统中 pthread_t 直接映射为 Task ID 值
- 对于一些特殊的系统,pthread_t 是一个结构体
Linux 多线程 API 函数
线程标识相等判断
int pthread_equal(pthread_t t1, pthread_t t2);
如果 t1 和 t2 相等,返回非 0 值,否则返回 0 值
注意:
Linux 系统编程时,可直接用 t1 == t2 的方式判断是否相等
编写可移植的多线程代码,使用 pthread_equal() 判断是否相等