【操作系统】进程与线程
优质
小牛编辑
127浏览
2023-12-01
更多面试题总结请看:【面试题】技术面试题汇总
进程是一个拥有资源和执行任务的单元体。进程拥有的资源包括:内存空间中的代码、数据等;I/O 资源;文件;处理机等。
线程是一个执行任务的单元体。线程只拥有处理机,线程之间共享进程的资源,如内存、I/O 等。
对比:
进程 | 线程 | |
---|---|---|
资源 | 进程是一个拥有资源和执行任务的单元体。 | 线程是一个执行任务的单元体,不拥有资源,线程之间共享地址空间 |
切换开销 | 开销很大 | 开销很小 |
通信 | IPC | 共享内存 |
健壮性 | 健壮,多个进程之间不会互相干扰 | 不健壮,一个线程出错会终止整个进程 |
为什么需要线程
进程切换是一个开销很大的操作。进程切换的开销主要包括:
- 处理机的上下文切换:保存和恢复相关寄存器的内容
- 与进程相关的数据结构更改:存储管理有关的记录信息(如页表)、文件管理有关数据(如文件描述符)、进程控制块中的各种队列(如阻塞队列、就绪队列、通信队列)等
进程的处理机资源和其他资源是一起分配的,进程切换的时候会整体切换,开销很大。如果我们只切换必需的、与处理机相关的信息,就可以有效减少开销。这种情况下,处理机分配的单位和其他的资源分配的单位不能再是一个实体。
由此引入线程:把一个进程分为多个执行任务的单元体,只为其分配处理机,这些执行任务的单元体就是线程。
线程的上下文切换过程
线程有自己的寄存器和栈。当上下文切换的时候,正在运行的线程会将寄存器的状态保存到 TCB(Thread Control Block)里(进程是 PCB,Process Control Block),然后恢复另一个线程的上下文。
图 1:单线程与多线程的示意图
和进程的区别是,线程只需要切换处理机执行的上下文,不会改变地址空间。这意味着:
- 不需要重新加载页表,切换开销少,提高效率
- 多个线程共享地址空间,有利有弊
线程的优缺点
优点:
- 提高效率:切换开销小
- 通信方便,共享内存;进程必须通过进程间通信 IPC
缺点:
- 一个线程出错,操作系统会结束整个进程,不够健壮;而多进程就没有这个问题
- 同一进程中的多个线程共享内存,会有并发问题
同一进程中的线程共享与独占的资源
共享资源:
- 内存空间
- 代码
- 公共数据(全局变量、静态变量)
- 堆
- 文件描述符
- 信号处理器
- 进程 ID / 进程组 ID
- …
独占资源,以及为什么需要独占:
- 线程 ID:在本进程中唯一,进程用来标识此线程
- 一组寄存器的值
- 栈:每个线程中的函数调用过程是独立的,因此需要有独立的栈
- 错误返回码:系统调用或库函数发生错误时,会设置全局变量
errno
,各个线程的错误返回码应该是独立的 - 信号屏蔽码:每个线程所感兴趣的信号不同,所以线程的信号屏蔽码应该由线程自己管理;但每个线程都共享本进程的信号处理器
可以参考图 1。
线程的实现方式
线程也像进程一样有多个状态:运行、就绪、阻塞…
从 Linux 内核的角度来看,线程和进程并没有被区别对待。无论线程还是进程,都是用 task_struct
结构表示的,只不过线程的 mm
(内存空间)和 files
(打开的文件)结构体是共享的,见进程、线程和文件描述符 - labuladong。
线程实现的方式有三种:
- 在内核实现
- 在用户空间实现
- 混合方式实现
每种实现方式的优缺点:TODO
技术面试题汇总
参考资料: