【问题标题】:Difference between kernel threads and user threads in a multi core cpu?多核cpu中内核线程和用户线程之间的区别?
【发布时间】:2020-04-23 04:36:35
【问题描述】:

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

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

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

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

因此,python 和 nodejs 程序都不能真正在多核环境中一次使用多个内核。

我说对了吗?

【问题讨论】:

    标签: python node.js multithreading kernel


    【解决方案1】:

    我既不熟悉 Python 也不熟悉 Node.js,但我可以帮助您解决其余的问题。

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

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

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

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

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

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

    最后,警告一句:关于内核线程浮动有很多错误信息和混乱。内核线程不是只执行内核代码的线程(并且执行内核代码的线程不一定是内核线程,这取决于您如何看待它)。

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

    【讨论】:

    • 谢谢ihonen,有几个问题。 1.)你能简要介绍一下内核线程的工作吗? 2.) 谁决定何时需要创建内核线程? 3.) 为什么我们需要内核线程上下文来执行用户线程,为什么不直接用户级线程?
    • @stonelazy 1) 内核可以随时停止任何线程并开始运行另一个线程。内核线程的工作是存储停止线程的执行上下文并帮助实现 CPU 调度。 2) 每当产生一个进程时,就会创建一个内核线程——然后由每个进程来请求内核在需要时创建更多线程。 3) 内核只知道内核线程,因此为了调度线程执行(即实际在 CPU 上运行),它必须是内核线程。所以你的进程必须至少有一个内核线程——否则它就不是一个进程。
    【解决方案2】:

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

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

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

    here an article about that

    如果你想为你的应用程序利用你机器的不同核心,你将不得不使用一个集群,你可以在其中找到 api there

    希望我回答了你的问题

    【讨论】:

      猜你喜欢
      • 2018-03-19
      • 2013-04-05
      • 2010-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-28
      • 2011-03-24
      • 1970-01-01
      相关资源
      最近更新 更多