CPU个时间片进程或线程的可调度单元?

Is a schedulable unit of CPU time slice process or thread?

我想弄清楚“CPU时间片的一个可调度单位”是“进程”还是“线程”(内核管理的线程)。我所说的“CPU 时间片的可调度单位”是指操作系统的 CPU 调度程序分配 CPU 时间片的单位。

根据维基百科中的“Short-term scheduling”,process用于指代可调度单元。

"This scheduler can be preemptive, implying that it is capable of forcibly removing processes from a CPU when it decides to allocate that CPU to another process"

此外,根据维基百科中的“Time slice”,

"The scheduler is run once every time slice to choose the next process to run."

此外,根据维基百科中的“Thread”,

"a process is a unit of resources, while a thread is a unit of scheduling and execution"

根据微软文档中的“Processes and Threads”,

"A thread is the basic unit to which the operating system allocates processor time."

根据 quora 中的“Is thread scheduling done by the CPU, kernel, or both?”,

"The CPU (hardware) just carries out instructions. The CPU itself has no concept of threads or scheduling, although there may be features in the CPU that support them.

"The operating system kernel (a set of instructions, aka software) executes on the CPU (hardware). A scheduling algorithm in the kernel of the operating system chooses which thread to execute next, and directs the CPU to begin executing the next instruction in that chosen thread".

澄清:我对“CPU时间片的可调度单元”的理解是“在给定的CPU时间内可以调度的单元” slice”(因为如果“可调度单位”是时间,那么这个问题对我来说意义不大)。

基于此,简而言之,对于给定的逻辑内核,“一个CPU时间片的可调度单元”可以看作是一个软件线程(更多特别是它的执行上下文由寄存器和进程信息组成。


操作系统调度程序在任务上运行。任务可以是线程、进程或其他不寻常的结构(例如数据流)。

现代主流操作系统主要在处理单元上调度线程(通常硬件线程也称为逻辑核心).您可以在 Microsoft documentation 中获得有关 Windows 调度程序如何工作的更多信息。文档明确指出:

A thread is the entity within a process that can be scheduled for execution

在 Linux 上,默认调度程序 CFS, operates on task (ie. task_struct data structure). Tasks can be a thread, a group of threads or a process. This was done that way so to make the scheduler more generic and also because this scheduler was designed long ago, when processors had only 1 core and people focused on processes rather than thread. The multi-core era since caused applications to use a lot of threads so to use available cores. As a result, nowadays, it is generally threads that are actually scheduled AFAIK. This is explained in the famous research paper The Linux Scheduler: a Decade of Wasted Cores(这也解释了 CFS 如何针对目标处理器进行操作)。

请注意,术语“进程”有时可以指代线程,因为线程有时被称为“轻量级进程”,而基本进程有时被称为“重型进程”。进程甚至可以是重进程和轻进程(即线程和实际进程)的通用术语。这是一个非常令人困惑的术语和语言误用(例如有时用于内核的术语“处理器”)。实际上,这在特定上下文中通常不是问题,因为线程和进程可以互换使用(在这种情况下,人们应该使用像“任务”这样的通用术语)。

至于“CPU时间片的可调度单元”,这个就比较复杂了。一个简单而天真的答案是:一个线程(它绝对不是单独的进程)。话虽如此,线程是一个 software-defined 概念(如进程)。它基本上是一个堆栈、几个寄存器和一个父进程(可能有一些 meta-information 和一个 TLS space)。 CPUs 不直接对此类数据结构进行操作。例如,CPU 没有线程堆栈的概念(它只是虚拟进程内存的一部分,就像其他内存一样)。他们只需要一个由寄存器和进程配置组成的执行上下文(在 protected mode). For sake of simplicity, we can say that they execute threads. Mainstream modern x86 processors are very complex, and each core is often able to run multiple threads at the same time. This is called simultaneous multithreading(又名 Hyper-Threading 用于英特尔处理器)。x86 物理内核通常由两个逻辑线程(即硬件线程)组成) 每个可以执行一个软件线程。

我认为你的误解实际上是对英文单词在这种情况下的意思的误解。

时间片是一段时间。也许只是几分之一秒。也许几秒钟。

线程和进程实际上是计算机将要执行的任务。 (我在这里进行了简化。任务的概念具有多重含义,即使在 IT 上下文中也是如此。在现代 OS 中,进程实际上是共享相同虚拟内存地址的线程集合 space.)

CPU1 或处理器是将 运行 一个(本机)线程的硬件。一台典型的计算机将有多个 CPU。但是,一台计算机中每个CPU一次只能运行一个线程

因此,操作系统需要将它知道的每个线程调度到 运行 到特定的 CPU。执行此操作的操作系统部分称为 调度程序

如果到 运行 的线程多于 CPU 到 运行 的线程,调度程序通常会将一个线程调度到 CPU 固定时间段时间;即 时间片 。当线程的时间片结束后,调度器会将其挂起并放回队列中,然后在CPU.

上调度另一个线程到运行

这个比喻是我们正在“分割”CPU 上的可用计算时间并在需要它的线程之间共享切片。

1 - 对于“CPU”的实际含义存在一些分歧。我认为它指的是通常所说的“核心”。英特尔令人困惑地引入了营销术语2“超线程”,它指的是“核心”的物理硬件可以运行作为两个独立的指令执行器的功能。但是,在超线程模式下,OS 调度程序 通常 将超线程视为不同的核心,因此这与您的问题无关。
2 - 超线程背后的实际概念可以追溯到 1960 年代,当时英特尔甚至还没有作为一家公司存在;参见 https://en.wikipedia.org/wiki/Barrel_processor


所以你的问题的答案是:

I want to clarify whether "a schedulable unit of CPU time slice" is "process" or "thread" (kernel managed thread).

时间片是CPU时间的可调度单位。

时间片既不是进程也不是线程。事实上,这甚至没有意义,因为“进程”和“线程”不是时间。


我同意@Solomon Slow 的评论。维基百科不权威。但真正的问题是,随着时间的推移,不同的页面由不同的人编写和编辑,他们经常使用不一致的 IT 术语。

我的建议是查找并阅读一本关于(现代)操作系统设计和体系结构的好教科书。 well-written 教科书 应该 使用术语self-consistent。

时间片是一个时间单位,例如在使用 HZ=100(每秒 100 个定时器中断)构建的传统 Linux 内核中为 10 毫秒。在一个任务在 CPU 核心上 运行ning 这么长时间后,内核重新获得对该 CPU 的控制并调用 schedule() 来决定这个 CPU 核心应该运行 接下来;它已经是 运行ning 的任务,或者另一个任务。

如果有外部中断进入,调度程序也可以提前 运行,尤其是在当前时间片即将结束时:如果有 higher-priority 任务正在等待 CPU ,例如在等待 I/O 或 sleep() 系统调用结束后,OS 将其调度到该核心是有意义的,而不是完成任何 [=] 的 time-slice 34=] 任务被中断。


Task 是一个有用的词,用于表示调度程序必须从中选择的内容。不暗示单独的进程或进程内的线程,也为内核任务留出空间,例如 Linux 中断处理程序“下半部分”不是线程或进程。

进程的每个线程都需要单独安排在 CPU 核心上执行(如果它没有被阻塞)。

您找到的有关调度进程的文章使用的简化假设是每个进程都是 single-threaded。

或者他们假设 1:n 线程模型,其中 OS 只知道整个进程的一个任务,多线程在 user-space 中完成,“green threads" 而不是本机线程。如今大多数主流 OSes 使用 1:1 线程模型,其中每个 C++ 或 Java 线程都是 OS 可见的单独可调度任务,尽管 n:m如果您有多个 OS-scheduled 任务,但没有 high-level-language 线程那么多,那么模型是可能的。