我想澄清一下我对多核环境中的内核线程和用户线程的理解。
如果 cpu 支持,只有内核创建的线程才能在 cpu 的不同内核上运行。用户级线程由库抽象在一个内核上,因此,所有用户级线程都运行在同一个内核上。
Python 线程一次只能运行一个,因为它们需要持有 GIL,因此无论 Python 线程的实现如何,在多核环境中一次只能使用 1 个内核。
在 nodejs 中有一个名为 eventloop 的主线程来处理所有的核心处理。所有与 io 相关的事件都被卸载到工作线程。但是现代计算机不使用 cpu 进行 io 事件,而是将 io 事件卸载到 io Controller 。所以所谓的工作线程实际上只是将 io 事件卸载到 io Controller 的抽象。没有创建真正的线程。
因此,python 和 nodejs 程序都不能真正在多核环境中一次使用多个内核。
我说对了吗?
最佳答案
我对 Python 和 Node.js 都不熟悉,但我可以帮助您解决其余的问题。
在我看来,了解用户线程最简单的方法是了解内核如何在单核系统中管理(kernel)线程。在这样的系统中,只有一个硬件线程,即在任何给定时间,只有一个线程可以在物理上在 CPU 上执行。显然,为了同时运行多个线程,内核需要在线程之间进行多路复用。这称为时间共享:内核在线程之间进行处理,在切换到另一个线程之前,每个线程只运行一小段时间(通常大约为 10 毫秒)。分配给每个进程的时间片足够短,因此看起来线程是并行运行的,而实际上它们是顺序运行的。这种明显的并行称为并发;真正的并行性需要硬件支持。
用户线程只是更进一步的同一种多路复用。
每个进程开始时只有一个内核线程,除非它明确要求内核,否则它不会得到更多。因此,在这样的单线程进程中,所有代码都在同一个内核线程上执行。这包括负责创建和管理用户线程的用户空间线程库,以及用户线程本身。创建用户线程不会导致创建内核线程——这正是用户空间线程的意义所在。该库管理自己创建的用户线程的方式与内核管理内核线程的方式非常相似;它们都执行线程调度,这意味着用户线程也在短时间内轮流运行,一次一个。
你会注意到这与上面描述的内核线程调度非常相似:在这个类比中,运行进程的单个内核线程是 CPU 的单个内核,用户线程是内核线程,用户线程空间线程库是内核。
如果进程在多个内核线程上运行(即它通过系统调用从内核请求更多线程),情况基本相同。用户线程只是运行它们的内核线程的本地数据结构,在每个用户线程上执行的代码只是在内核线程上下文中在 CPU 上执行的代码;当一个用户线程切换到另一个时,内核线程实质上执行了一个跳转并开始在另一个位置(由用户线程的指令指针指示)执行代码。因此,从多个内核线程创建多个用户线程是完全可能的,尽管这在很大程度上违背了使用用户线程的初衷。
Here是一篇关于 Python 中的多线程(并发)和多处理(并行)的文章,您可能会感兴趣。
最后,一句警告:关于内核线程的 float 有很多错误信息和混淆。内核线程不是只执行内核代码的线程(执行内核代码的线程不一定是内核线程,这取决于您如何看待它)。
我希望这能为您解决问题 - 如果没有,请要求澄清,我会尽力提供。
关于python - 多核cpu中内核线程和用户线程之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59598468/