一对一的多线程模型

时间:2018-03-06 05:46:12

标签: multithreading operating-system

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

  

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

我在这里有两个问题:

  1. 如何阻止一个线程并在内核线程上映射其他线程? 我们不知道如果一个线程被阻止,整个过程就是这样 用户级线程被阻止?
  2. 操作系统考虑用户级线程 仅作为一个线程。它不能分配给多个 处理器/内核。下面给出的线不是那么矛盾的 理念?
      

    它还允许多个线程并行运行   多处理机

2 个答案:

答案 0 :(得分:1)

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

内核线程

由内核创建和管理的线程。每个内核级线程由一些数据结构表示,该数据结构包含与线程相关的信息。在Linux的情况下,它是task_struct。内核线程是CPU调度程序考虑用于调度的唯一线程。

用户帖子

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

用户级到内核级映射

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

一对一模式

在这种情况下,每当您创建用户级线程时,您的库都会要求内核创建新的内核级线程。对于Linux,您的库将使用克隆系统调用来创建内核级线程。

多对一模式

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

现在回答您的问题

  

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

如果您使用多对一模型,那么您将只有一个内核级线程用于所有用户级线程,因此它们无法在不同的CPU上运行。

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

答案 1 :(得分:1)

你的书很难受。

有真正的线程(也就是内核线程,1比1模型),还有模拟线程(也就是用户线程,多到1个模型)。

有些书通过向许多模型投掷假设的许多模型而使这更令人困惑。

用户线程已过时。现在任何值得阅读的操作系统书都会以这种方式对待它们并用历史术语来描述它们。

  

如何阻止一个线程并在内核线程上映射其他线程?我们不知道如果一个线程被阻止,那么该用户级线程的整个进程都被阻止了吗?

您要么拥有用户线程,要么拥有内核线程。做这两件事的应用程序将被搞砸了。

  

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

在过去的几天里,一个进程被认为是一个执行流和一个地址空间。没有线程。当线程变得必要时(主要是由于需要Ada支持),它们是使用计时器模拟的。线程的行为因操作系统而异。

在Eunuchs变体中,阻塞调用完全阻止了该过程。因此,在模拟(用户)线程中,一个线程中的阻塞调用将阻塞所有线程。在所有操作系统上都不是这样。

现在,进程是一个或多个执行流和地址空间。这就是你应该学习的东西;不是一堆技术人员。

本书以1对1或多对1模型的形式讨论线程,仅适用于线盒猫。