多核CPU中内核线程和用户线程的区别?

Sau*_*Jha 3 python multithreading kernel node.js

我想澄清一下我对多核环境中内核线程和用户线程的理解。

如果CPU支持的话,只有内核创建的线程才能在CPU的不同核心上运行。用户级线程由库抽象在单个核心上,因此,所有用户级线程都在同一核心上运行。

Python 线程一次只能运行一个,因为它们需要持有 GIL,因此无论 Python 线程的实现如何,在多核环境中一次只能使用 1 个核心。

在nodejs中有一个名为eventloop的主线程来处理所有核心处理。所有与 io 相关的活动都被卸载到工作线程。但现代计算机并不使用 cpu 进行 io 活动,而是将 io 活动卸载到 io 控制器。因此,所谓的工作线程实际上只是将 io 活动卸载到 io 控制器的抽象。没有创建真正的线程。

因此,无论是 Python 还是 Node.js 程序都无法在多核环境中真正同时使用多个核心。

我说得对吗?

iho*_*nen 6

我对 Python 和 Node.js 都不熟悉,但我可以帮助您解决其余问题。

在我看来,理解用户线程的最简单方法是理解内核如何在单核系统中管理(kernel)线程。在这样的系统中,只有一个硬件线程,即在任何给定时间只有一个线程可以物理地在CPU上执行。显然,为了同时运行多个线程,内核需要在线程之间进行多路复用。这称为时间共享:内核在线程之间进行切换,在切换到另一个线程之前,每个线程仅运行一段时间(通常约为 10 毫秒)。给予每个进程的时间量足够短,因此看起来线程是并行运行的,而实际上它们是顺序运行的。这种明显的并行性称为并发性;真正的并行性需要硬件支持。

用户线程只是更进一步的同一种多路复用。

每个进程最初仅以一个内核线程启动,除非明确询问内核,否则它不会获得更多线程。因此,在这样的单线程进程中,所有代码都在同一个内核线程上执行。这包括负责创建和管理用户线程的用户空间线程库以及用户线程本身。创建用户线程不会导致创建内核线程 - 这正是用户空间线程的要点。该库管理自己创建的用户线程的方式与内核管理内核线程的方式非常相似;它们都执行线程调度,这意味着用户线程也会在短时间内轮流运行,一次一个。

您会注意到,这与上面描述的内核线程调度非常相似:在这个类比中,进程运行的单个内核线程是 CPU 的单个核心,用户线程是内核线程,用户空间线程库是内核。

如果进程在多个内核线程上运行(即,它通过系统调用从内核请求更多线程),情况基本保持不变。用户线程只是它们运行所在的内核线程本地的数据结构,并且在每个用户线程上执行的代码只是在内核线程上下文中的CPU上执行的代码;当用户线程切换到另一个时,内核线程本质上执行跳转并开始在另一个位置(由用户线程的指令指针指示)执行代码。因此,完全有可能从多个内核线程创建多个用户线程,尽管这几乎违背了首先使用用户线程的目的。

是一篇关于 Python 中的多线程(并发)和多处理(并行)的文章,您可能会感兴趣。

最后,警告一下:关于内核线程存在很多错误信息和混乱。内核线程并不是执行内核代码的线程(执行内核代码的线程不一定是内核线程,具体取决于您如何看待它)。

我希望这能为您解决问题 - 如果没有,请要求澄清,我会尽力提供。