我想澄清一下我在多核环境中对内核线程和用户线程的理解。
如果cpu支持,则只有内核创建的线程才能在cpu的不同内核上运行。库将用户级线程抽象到单个内核上,因此,所有用户级线程都在同一内核上运行。
Python线程一次只能运行一个,因为它们需要保持GIL,因此,无论python线程的实现如何,在多核环境中一次只能使用1个内核。
在nodejs中,有一个名为eventloop的主线程可以处理所有核心处理。所有与io相关的活动都被卸载到工作线程中。但是现代计算机不使用cpu进行io活动,而是将io活动卸载到io控制器。因此,所谓的工作线程实际上只是将io活动卸载到io控制器的一种抽象。没有创建真正的线程。
因此,在多核环境中,python和nodejs程序都不能一次真正使用多个核。
我说对了吗?
答案 0 :(得分:2)
我对Python和Node.js都不熟悉,但是我可以帮助您解决其他问题。
据我估计,了解用户线程的最简单方法是了解内核如何在单核系统中管理(内核)线程。在这样的系统中,只有一个硬件线程,即在任何给定时间,只有一个线程可以在CPU上实际执行。显然,为了同时运行多个线程,内核需要在线程之间进行多路复用。这称为时间共享:内核在线程之间进行切换,在切换到另一个线程之前,每个线程只运行一小段时间(通常以10毫秒为顺序)。分配给每个进程的时间量足够短,因此看起来线程是并行运行的,而实际上它们是顺序运行的。这种表观并行性被称为 concurrency ;真正的并行性需要硬件支持。
用户线程只是一种进一步的复用。
每个进程最初都只从一个内核线程开始,除非明确地询问内核,否则它不会得到更多。因此,在这样的单线程进程中,所有代码都在同一内核线程上执行。这包括负责创建和管理用户线程以及用户线程本身的用户空间线程库。创建用户线程不会导致创建内核线程-这恰好是用户空间线程的关键所在。该库管理自己创建的用户线程的方式与内核管理内核线程的方式几乎相同。它们都执行线程 scheduling ,这意味着用户线程也将在短时间内轮流运行,一次一次。
您会注意到,这与上述内核线程调度非常相似:以此类推,运行进程的单个内核线程是CPU的单个内核,用户线程是内核线程,而用户-空间线程库是内核。
如果该进程在多个内核线程上运行(即它已通过系统调用从内核请求更多线程),则情况大致相同。用户线程只是运行它们的内核线程本地的数据结构,在每个用户线程上执行的代码就是在内核线程上下文中在CPU上执行的代码;当用户线程切换到另一个线程时,内核线程实质上执行跳转并开始在另一个位置执行代码(由用户线程的指令指针指示)。因此,完全有可能从多个内核线程创建多个用户线程,尽管这首先会破坏使用用户线程的目的。
Here是一篇有关Python中的多线程(并发)和多处理(并行性)的文章,您可能会觉得有趣。
最后,要提一个警告:关于周围浮动的内核线程,存在很多错误信息和困惑。内核线程不是不是仅执行内核代码的线程(并且执行内核代码的线程不一定是内核线程,这取决于您的外观)。
我希望这可以为您解决-如果没有,请澄清一下,我会尽力提供。
答案 1 :(得分:1)
Nodejs作为您所说的主线程,它将执行所有javascript代码。
对于花费更多的所有I / O执行,例如fs
或dns
,nodejs使用的libuv
会将工作分流到不同的线程。如果池中的线程数大于计算机上的内核数,则计算机的资源将被分配。
最后,I / O将使用您可用的不同核心CPU。
如果要为应用程序利用计算机的不同内核,则必须使用一个群集,在该群集中可以找到api there
希望我回答了你的问题