操作系统笔记 – 线程
在传统操作系统中,每个进程都有一个地址空间、一个控制线索和一个程序计数器,所以一个进程内部是顺序执行的。但是在很多现代操作系统中,为这两个角色赋予两个实体:作为资源分配单位时,进程只作为资源拥有者,负责申请和占有所需的全部资源(除CPU);为进程参与调度和运行的职责赋予新的实体——线程(Thread)。
3.1 什么是线程
3.1.1 线程的概念
线程是进程中执行运算的最小单位,也是执行处理机调度的基本单位。在多处理器系统中,各个线程可以在单独的CPU上运行,从而大大提高了系统的效率。
引入线程概念的原因:
- 使并行实体获得共享同一地址空间和所有可用数据的能力。
- 便于切换,代价地。由于线程只具有少量私有资源,不具有单独的地址空间,所以线程又被称为轻载进程(LWP)。在许多系统中,创建一个线程要比创建一个进程快10到100倍。
- 可以改善系统的性能。
3.1.2 线程的组成
每个线程都有一个thread结构,即线程控制块,用于保存自己私有的信息。线程主要由以下4个基本部分组成:
- 一个唯一的线程标识符
- 描述处理器工作状况的一组寄存器的内容
- 每个thread结构有两个指针,一个指向核心栈,一个指向用户栈。
- 一个私有存储区。
3.1.3 线程的状态
与进程相似,线程也有若干状态:
- 运行状态:线程正在CPU上执行程序,真正处于活动状态。
- 就绪状态:线程具备运行条件,一旦分配到CPU,就可以马上投入运行。
- 阻塞状态:线程正等待某个事件发生。
- 终止状态:当一个线程完成任务后,它占用的寄存器和栈等私有资源会被系统回收,重新分配给其他线程。
3.1.4 线程和进程的关系
- 一个进程可以有多个线程,但至少有一个线程。而一个线程只能在一个进程的地址空间内活动。
- 资源分配给进程,同一进程的所有线程共享该进程的所有资源。
- 处理机分配给线程,即真正在处理机上运行的使线程。
- 线程在执行过程中需要协作同步,不同进程的线程之间要利用消息通信的办法实现同步。
3.2 线程的实现方式
在很多系统都实现了线程,如Windows,Linux等。但是它们的实现方式并不完全相同,主要有用户级线程和核心级线程两种实现方式。
3.2.1 用户级线程
在这种方式下,整个管理线程的线程库放在用户空间,管理线程的工作全部由应用程序完成,核心对进程一无所知,只对常规进程实施管理。
用户级线程方式优点主要有:
- 线程切换速度很快,无需进行系统调度。
- 调度算法可以是应用程序专用的。允许不同的应用程序采用适合自己要求的不同的调度算法,并且不干扰底层的操作系统的调度程序。
- 用户级线程可以运行在任何操作系统上,包括不支持线程机制的操作系统。线程库是一组应用级的实用程序,所有应用程序都可以共享。
用户级线程方式缺点主要有:
- 系统调用的阻塞问题。多数系统调用都是阻塞式的,当一个线程执行系统调用时,不仅他自己被阻塞,而且同一个进程内的所有线程都被阻塞。
- 在单纯用户级线程方式中,多线程应用程序不具有多处理器的优点。因为核心只为每个进程一次分配一个处理器,每次只执行该进程的一个线程,在该线程自愿放弃CPU之前,不会执行该进程内的其他线程。
3.2.2 核心级线程
在这种方式下,核心知道线程存在,并对它们实施管理。线程表不在每个进程的空间中,而在核心空间中。当一个线程想创建一个新线程或者删除一个现有线程时,必须执行系统调用。
核心级线程方式优点主要有:
- 在多处理器系统中,核心可以同时调度统一进程的多个线程,真正实现并行操作。
- 如果一个进程的某个线程阻塞了,核心可以调度同一个进程的另一个线程。
- 核心线程本身也可以是多线程的。
核心级线程方式缺点主要有:
- 控制转移开销大。在同一进程中,从一个线程切换到另一个线程时,需要将模式切换到核心态。在单CPU系统中,针对线程的创建、调度、执行直至完成的事件以及线程间同步开销的时间,核心级线程方式都比用户级线程方式高一个数量级。
- 调度算法由核心确定,应用进程无法影响线程的切换。