一对一的多线程模型

fre*_*ner 6 multithreading operating-system

在 silberschatz“操作系统概念”一书中,第 4.3.2 节说

一对一模型通过在线程进行阻塞系统调用时允许另一个线程运行来提供比多对一模型更多的并发性。它还允许多个线程在多处理器上并行运行。

我在这里有两个问题:

  1. 一个线程如何被阻塞而另一个线程被映射到内核线程上?难道我们不知道,如果一个线程被阻塞,那么该用户级线程的整个进程都会被阻塞吗?
  2. 操作系统仅将用户级线程视为一个线程。它不能分配给多个处理器/内核。下面给定的行不是与这个想法相矛盾吗?

    它还允许多个线程在多处理器上并行运行

mig*_*WOZ 8

你对用户级线程和内核级线程的理解是不正确的,特别是你需要理解用户级线程是如何映射到内核级线程的。所以首先让我们定义一些术语

内核线程

由内核创建和管理的线程(可调度任务)。每个内核级线程都由一些包含与线程相关的信息的数据结构表示。在 Linux 的情况下,它是task_struct. 内核线程是唯一被 CPU 调度器考虑进行调度的线程。

注意:内核线程有点用词不当,因为 Linux 内核不区分线程和进程,可调度任务会更好地描述这个实体

用户线程

由内核级别以上的某些库(例如JVM)创建和管理的线程。创建这些线程的库负责它们的管理,即哪个线程在何时运行。

用户级到内核级映射

现在,您可以根据需要创建任意数量的用户级线程,但要执行它们,您需要创建一些内核级线程 ( task_struct)。可以通过多种方式创建内核级线程

一对一模型

在这种情况下,无论何时创建用户级线程,您的库都会要求内核创建一个新的内核级线程。在 Linux 的情况下,您的库将使用 clone 系统调用来创建内核级线程。

多对一模式

在这种情况下,您的库仅创建一个内核级线程 ( task_struct)。无论您创建多少个用户级线程,它们都共享相同的内核级线程,就像在单核 CPU 上运行的进程一样。要理解的一点是,您的库在这里的作用很像 CPU 调度程序,它在单个内核级线程上调度许多用户级线程。

现在回答你的问题

操作系统仅将用户级线程视为一个线程。它不能分配给多个处理器/内核。下面给定的行不是与这个想法相矛盾吗?

如果您使用多对一模型,在这种情况下,您的所有用户级线程将只有一个内核级线程,因此它们不能在不同的 CPU 上运行。

但是如果您使用一对一模型,那么您的每个用户级线程都有一个相应的内核级线程,可以单独调度,因此如果您有多个 CPU,用户级线程可以在不同的 CPU 上运行。

  • @freshlearner Linux 不区分进程和线程。当你使用 clone 系统调用创建一个新任务时,你可以使用一些标志来指定这个新任务将与其父任务共享哪些数据结构。如果您指定这些标志使得父子之间不发生共享,那么实际上您已经创建了一个新进程。另一方面,如果您指定这些标志以实现最高共享,那么新任务实际上是一个线程。 (2认同)