多核cpu中内核线程和用户线程之间的差异



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

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

Python线程一次只能运行一个,因为它们需要保存GIL,所以无论Python线程的实现如何,在多核环境中一次只能使用一个内核。

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

因此,在多核环境中,无论是python还是nodejs程序都不能真正一次使用多个核心。

我说得对吗?

我既不熟悉Python也不熟悉Node.js,但我可以帮助您完成其余的工作。

据我估计,理解用户线程的最简单方法是理解内核如何在单核系统中管理(内核)线程。在这样的系统中,只有一个硬件线程,也就是说,在任何给定时间,CPU上只能物理地执行一个线程。显然,为了同时运行多个线程,内核需要在线程之间进行多路复用。这被称为时间共享:内核在线程之间进行切换,在切换到另一个线程之前,每个线程只运行一段时间(通常是10ms)。给每个进程的时间段足够短,因此线程看起来是并行运行的,而实际上它们是按顺序运行的。这种明显的并行性称为

并发性用户线程就是更进一步的复用。

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

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

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

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

最后,提醒一下:关于内核线程,有很多错误信息和混乱。内核线程是而不是一个只执行内核代码的线程(执行内核代码不一定是内核线程,这取决于您如何看待它)。

我希望这能为你澄清——如果没有,请要求澄清,我会尽力提供。

Nodejs作为主线程,它将执行所有javascript代码。

对于成本更高的所有I/O执行,如fsdns,nodejs使用的libuv将把工作卸载到不同的线程。如果池中的线程数大于机器上的核心数,则机器的资源将被分配。

最后,I/O将使用不同的可用核心cpu。

这是一篇关于的文章

如果你想为你的应用程序利用机器的不同核心,你必须使用一个集群,在那里你可以找到的api

希望我能回答你的问题

最新更新