更多面试题总结请看:🗂【面试题】技术面试题汇总

进程是一个拥有资源执行任务的单元体。进程拥有的资源包括:内存空间中的代码、数据等;I/O 资源;文件;处理机等。

线程是一个执行任务的单元体。线程只拥有处理机,线程之间共享进程的资源,如内存、I/O 等。

对比:

  进程 线程
资源 进程是一个拥有资源执行任务的单元体。 线程是一个执行任务的单元体,不拥有资源,线程之间共享地址空间
切换开销 开销很大 开销很小
通信 IPC 共享内存
健壮性 健壮,多个进程之间不会互相干扰 不健壮,一个线程出错会终止整个进程

为什么需要线程

进程切换是一个开销很大的操作。进程切换的开销主要包括:

  • 处理机的上下文切换:保存和恢复相关寄存器的内容
  • 与进程相关的数据结构更改:存储管理有关的记录信息(如页表)、文件管理有关数据(如文件描述符)、进程控制块中的各种队列(如阻塞队列、就绪队列、通信队列)等

进程的处理机资源和其他资源是一起分配的,进程切换的时候会整体切换,开销很大。如果我们只切换必需的、与处理机相关的信息,就可以有效减少开销。这种情况下,处理机分配的单位和其他的资源分配的单位不能再是一个实体。

由此引入线程:把一个进程分为多个执行任务的单元体,只为其分配处理机,这些执行任务的单元体就是线程。

线程的上下文切换过程

线程有自己的寄存器和栈。当上下文切换的时候,正在运行的线程会将寄存器的状态保存到 TCB(Thread Control Block)里(进程是 PCB,Process Control Block),然后恢复另一个线程的上下文。

图 1:单线程与多线程的示意图

和进程的区别是,线程只需要切换处理机执行的上下文,不会改变地址空间。这意味着:

  1. 不需要重新加载页表,切换开销少,提高效率
  2. 多个线程共享地址空间,有利有弊

线程的优缺点

优点:

  • 提高效率:切换开销小
  • 通信方便,共享内存;进程必须通过进程间通信 IPC

缺点:

  • 一个线程出错,操作系统会结束整个进程,不够健壮;而多进程就没有这个问题
  • 同一进程中的多个线程共享内存,会有并发问题

同一进程中的线程共享与独占的资源

共享资源:

  • 内存空间
    • 代码
    • 公共数据(全局变量、静态变量)
  • 文件描述符
  • 信号处理器
  • 进程 ID / 进程组 ID

独占资源,以及为什么需要独占:

  • 线程 ID:在本进程中唯一,进程用来标识此线程
  • 一组寄存器的值
  • 栈:每个线程中的函数调用过程是独立的,因此需要有独立的栈
  • 错误返回码:系统调用或库函数发生错误时,会设置全局变量 errno,各个线程的错误返回码应该是独立的
  • 信号屏蔽码:每个线程所感兴趣的信号不同,所以线程的信号屏蔽码应该由线程自己管理;但每个线程都共享本进程的信号处理器

可以参考图 1。

线程的实现方式

线程也像进程一样有多个状态:运行、就绪、阻塞…

从 Linux 内核的角度来看,线程和进程并没有被区别对待。无论线程还是进程,都是用 task_struct 结构表示的,只不过线程的 mm(内存空间)和 files(打开的文件)结构体是共享的,见进程、线程和文件描述符 - labuladong

线程实现的方式有三种:

  • 在内核实现
  • 在用户空间实现
  • 混合方式实现

每种实现方式的优缺点:TODO

🗂 技术面试题汇总


参考资料: