【发布时间】:2011-05-23 01:09:45
【问题描述】:
我正在研究线程,但对一件事有点困惑。
如果我在双核/四核 CPU 上运行具有多个线程的单个进程,不同的线程会在不同的内核上同时运行吗?
提前致谢。
【问题讨论】:
我正在研究线程,但对一件事有点困惑。
如果我在双核/四核 CPU 上运行具有多个线程的单个进程,不同的线程会在不同的内核上同时运行吗?
提前致谢。
【问题讨论】:
视情况而定。
至少在 Linux 上,每个任务都被分配到一组可以执行的 CPU (processor affinity)。并且,至少在 Linux 上,调度器会尝试将任务调度到与上次相同的处理器上,以便获得 CPU 缓存重用的最大好处。有趣的是,当系统处于负载状态时,它并不总是重新平衡,因此可以运行一个非常热且有争议的核心,而让三个核心保持凉爽且相对空闲。 (我已经在 Folding @ Home 客户端看到了这种确切的行为。)
您可以强制使用pthread_setaffinity_np(3) 例程(用于线程应用程序)或sched_setaffinity(2) (用于更传统的Unix 风格fork(2)ed 应用程序)来实现所需的亲和性。或者您可以使用taskset(1) 程序在启动应用程序之前或之后设置关联。 (这是我对愚蠢的 Folding @ Home 客户端采用的方法——很容易修改 initscript 以调用 taskset(1) 以正确设置每个客户端进程的亲和力,因此每个客户端都有自己的核心并且没有竞争与其他客户端在不同的同级超线程“伪造”执行核心上的资源。)
【讨论】:
这取决于语言、库和操作系统,以及线程应用程序是否在同一时间点实际上有多个可运行线程,但通常答案是“是”。
【讨论】:
您永远无法确定这一事实,但如果它是处理器密集型的(例如游戏),那么很可能是的。
【讨论】:
在这种情况下,您需要使用 volatile 关键字将处理器的每个内核与内存同步,以确保处理器的每个内核都从内存中获取新的更新值。
【讨论】:
线程有时会同时运行,有时不会。这完全取决于您使用的包和操作系统以及每个线程的 CPU 密集程度。
【讨论】:
我认为您正在失去并发背后的想法;这并不是说您要在多个内核上运行进程。相反,您不需要一直阻塞一个进程。一个完美的例子是线程网络监听器。你想执行一个接受,它实际上会创建一个新的客户端->服务器套接字。在此之后,您希望对该套接字进行一些处理,同时仍然能够建立新的连接。这是您想要生成一个线程来执行处理的地方,以便接受可以回到正轨以等待新的连接。
【讨论】: