操作系统学习笔记:线程

参考资料: 《现代操作系统 3th edtion》原书第二章 进程与线程
在 xmind 上记录

一、线程使用原因

  • 主要原因是,在许多应用中同时发生着多种活动。其中某些活动随着时间的推移会被阻塞。通过将这些应用程序分解成可以准并行运行的多个顺序线程,程序设计模型会变得更简单

  • 第二个关于需要多线程的理由是,由于线程比进程更轻量级,所以它们比进程更容易(即更快)创建, 也更容易撤销

  • 第三个原因涉及性能方面的讨论。若多个线程都是CPU密集型的,那么并不能获得性能上 的增强,但是如果存在着大量的计算和大量的I/O处理,拥有多个线程允许这些活动彼此重叠进行,从而会 加快应用程序执行的速度。

  • 最后,在多CPU系统中,多线程是有益的,在这样的系统中,真正的并行有了实现的可能

二、经典的线程模型

  • CPU在线程之间的快速切换,制造了线程并行运行的假象

  • 所有的线程都有完全一样的地址空间,这 意味着它们也共享同样的全局变量

  • 和传统进程一样(即只有一个线程的进程),线程可以处于若干种状态的任何一个:运行、阻塞、就绪 或终止

每个线程有其自己的堆栈

三、POSIX线程

  • 为实现可移植的线程程序,IEEE在IEEE标准1003.1c中定义了线程的标准。它定义的线程包叫做 Pthread。

  • 创建一个新线程需要使用pthread_create调用

  • 当一个线程完成分配给它的工作时,可以通过调用pthread_exit来终止

  • 通过pthread_join线程调用 来等待别的特定线程的终止

  • 一个线程逻辑上没有阻塞,但感觉上它已经运行了足够长时间并且希望给另外一 个线程机会去运行。这时可以通过调用pthread_yield完成这一目标

四、实现线程

在用户空间中实现线程

  • 把整个线程包放在用户空间中,内核对线程包一无所知

  • 从内核角度考虑,就是按正常的 方式管理,即单线程进程

  • 在用户空间管理线程时,每个进程需要有其专用的线程表(thread table),用来跟踪该进程中的线程

  • 优点

    • 这种方法第一个,也是最明显的优点是,用户级线程包可以在不支持线程的操作 系统上实现
    • 进行线程切换至少比陷入内核要快一个数量级(或许更多),这是使用用户级线程包的极大的优点
    • 它允许每个进程有自己定制的调度算法
  • 存在的问题

    • 第一个问题是如何实现阻塞系统调 用
    • 如果一个线程开始运行,那么在该进程中的其他线程就不能运行,除非第一个线程自动放弃CPU

在内核中实现线程

  • 在内核中有用来记录系统中所有线程的线程表

  • 在内核中创建或撤销线程的代价比较大

  • 当 一个线程阻塞时,内核根据其选择,可以运行同一个进程中的另一个线程(若有一个就绪线程)或者运行另 一个进程中的线程

  • 内核线程不需要任何新的、非阻塞系统调用

  • 调度程序激活机制

    • 调度程序激活工作的目标是模拟内核线程的功能,但是为线程包提供通常在用户空间中才能实现的更好 的性能和更大的灵活性
    • 如果线程阻塞在某个系统调用或页面故障上,只要在同一个进程中有 任何就绪的线程,就应该有可能运行其他的线程
    • 当使用调度程序激活机制时,内核给每个进程安排一定数量的虚拟处理器,并且让(用户空间)运行时 系统将线程分配到处理器上
    • 上行调用

混合实现

  • 使用内核级线程,然后将用户级线程与某些或者全部内核线程多路复用起来
  • 采用这种方法,内核只识别内核级线程,并对其进行调度。其中一些内核级线程会被多个用户级线程多 路复用

五、弹出式线程

  • 一个消息的到达导致系统创建一个处理 该消息的线程

  • 使用弹出式线程的结 果是,消息到达与处理开始之间的时间非常短

六、多线程代码的问题

  • 全局变量的逻辑,比如系统错误变量errno因线程切换造成歧义

  • 库过程不可重入,即对于任何给定的过程,当前面的调用尚没有结束之前,不可以进行第二次调用,比如网络协议的缓冲区

XMind: ZEN - Trial Version

你可能感兴趣的:(读书笔记)