线程数多于CPU核心数时多线程运行机制咨询
多线程在少于核心数的CPU上的运行机制解释
#include <iostream> #include <thread> #include <unistd.h> using namespace std; void taskA() { for(int i = 0; i < 10; ++i) { sleep(1); printf("TaskA: %d\n", i*i); fflush(stdout); } } void taskB() { for(int i = 0; i < 10; ++i) { sleep(1); printf("TaskB: %d\n", i*i); fflush(stdout); } } void taskC() { for(int i = 0; i < 10; ++i) { sleep(1); printf("TaskC: %d\n", i*i); fflush(stdout); } } void taskD() { for(int i = 0; i < 10; ++i) { sleep(1); printf("TaskD: %d\n", i*i); fflush(stdout); } } void taskE() { for(int i = 0; i < 10; ++i) { sleep(1); printf("TaskE: %d\n", i*i); fflush(stdout); } } void taskF() { for(int i = 0; i < 10; ++i) { sleep(1); printf("TaskF: %d\n", i*i); fflush(stdout); } } void taskG() { for(int i = 0; i < 10; ++i) { sleep(1); printf("TaskG: %d\n", i*i); fflush(stdout); } } void taskH() { for(int i = 0; i < 10; ++i) { sleep(1); printf("TaskH: %d\n", i*i); fflush(stdout); } } int main(void) { thread t1(taskA); thread t2(taskB); thread t3(taskC); thread t4(taskD); thread t5(taskE); thread t6(taskF); thread t7(taskG); thread t8(taskH); t1.join(); t2.join(); t3.join(); t4.join(); t5.join(); t6.join(); t7.join(); t8.join(); return 0; }
这一现象的核心是操作系统的线程调度机制,结合你的代码特性,具体可以拆解为以下几点:
时间片轮转与上下文切换
操作系统会给每个线程分配极短的执行时间片(通常是几毫秒级别)。当一个线程的时间片耗尽,或者主动进入阻塞状态(比如调用sleep),操作系统会暂停该线程的执行,保存它的上下文(比如寄存器状态、程序计数器等),然后切换到另一个就绪线程,恢复其上下文并让它在CPU上执行。这种切换速度极快,从用户视角看,多个线程就像是在同时运行。你的线程大部分时间处于阻塞状态
每个任务线程里都有sleep(1)调用,这会让线程主动放弃CPU,进入睡眠阻塞状态,此时操作系统会立刻把CPU资源分配给其他处于就绪状态的线程。你的8个线程大部分时间都在等待sleep结束,CPU可以在它们之间快速切换,所以你会看到8个任务的输出交替出现,看起来像是并行执行。并发 vs 真正并行
你的4个CPU核心可以真正同时执行4个线程(硬件级并行),但剩下的4个线程是通过操作系统的调度,在核心空闲时(比如其他线程sleep)或者时间片轮转来获得执行时间,整体表现为并发——即多个线程在同一时间段内交替执行,从用户角度感知就是“同时运行”。
内容的提问来源于stack exchange,提问作者Narayan Jee Jha
相关产品推荐
相关产品推荐

