Linux 中的线程模型
在 Linux 下,线程本质上是进程内的一个执行分支。内核并没有真正意义上的独立线程数据结构,而是复用进程的数据结构和管理算法来模拟线程(即轻量级进程 LWP)。这意味着线程在进程的地址空间内运行,共享大部分资源,但拥有独立的执行流。
线程与进程的区别
操作系统以进程为单位分配资源,而线程是调度的基本单位。从内核视角看,进程是承担系统资源分配的基本实体,线程则是进程内部的执行流资源。
- 进程:多个内核数据结构 (task_struct) + 代码和数据。
- 线程:共享进程数据,但拥有自己的线程 ID、寄存器栈、errno、信号屏蔽字和调度优先级。
所有线程共享同一地址空间,Text Segment 和 Data Segment 都是共享的。全局变量可被各线程访问,文件描述符表、信号处理方式、当前工作目录等环境信息也共享。
虚拟地址转换与内存布局
虚拟地址到物理地址的转换涉及页表机制。对于 32 位虚拟地址,CPU 通过页表找到物理地址后,结合数据类型(int/double/char)确定偏移量。这种机制决定了线程切换时,上下文切换的成本主要在于寄存器和栈的保存恢复,而不需要重新加载整个地址空间的映射。
为什么线程更轻量化?
相比进程,线程的生命周期管理更加高效:
- 创建与释放:开销更小,因为不需要复制完整的地址空间。
- 切换成本:线程切换无需刷新 Cache 中缓存的热数据,CPU Cache 命中率更高。
线程的优缺点
优点:
- 创建新线程代价远小于进程。
- 切换所需操作系统工作少。
- 能充分利用多处理器并行计算。
- I/O 密集型应用中,可在等待慢速 I/O 时执行其他计算任务。
缺点:
- 性能损失:过多计算密集型线程会导致同步和调度开销增加。
- 健壮性降低:时间分配偏差或共享变量未保护易导致 Bug。
- 缺乏访问控制:单个线程崩溃可能导致整个进程终止。
- 编程难度高:调试复杂,需处理竞态条件。
pthread 库使用指南
Linux 内核没有直接的线程系统调用,而是提供轻量级进程接口。用户层通常使用 pthread 库进行封装。
创建线程
使用 pthread_create 启动新线程。参数包括线程 ID 输出指针、属性设置、启动函数指针及传递参数。
#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;
void *threadRoutine(void *args) {
while() {
cout << << () << endl;
();
}
}
{
tid;
(&tid, , threadRoutine, );
() {
cout << << () << endl;
();
}
;
}

