C 多线程可以在单处理器系统上实现吗?
我一直遵循这样一个概念,即多线程只能在多处理器系统上实现,其中有多个处理器分配给每个线程,并且每个线程可以同时执行。在这种情况下没有调度,因为每个线程都有各自专用的资源。 但我最近在某个地方读到,我也可以在单处理器系统上进行多线程处理。C 多线程可以在单处理器系统上实现吗?,c,windows,multithreading,winapi,C,Windows,Multithreading,Winapi,我一直遵循这样一个概念,即多线程只能在多处理器系统上实现,其中有多个处理器分配给每个线程,并且每个线程可以同时执行。在这种情况下没有调度,因为每个线程都有各自专用的资源。 但我最近在某个地方读到,我也可以在单处理器系统上进行多线程处理。 对吗?如果是的话,那么单处理器系统和多处理器系统之间有什么区别呢?当然可以在单处理器系统上完成,事实上这样做要容易得多。它的工作方式与运行多个进程相同——内核通过计时器中断或其他类似机制挂起一个进程,保存其机器状态,并用另一个进程先前保存的状态替换它的机器状态—
对吗?如果是的话,那么单处理器系统和多处理器系统之间有什么区别呢?当然可以在单处理器系统上完成,事实上这样做要容易得多。它的工作方式与运行多个进程相同——内核通过计时器中断或其他类似机制挂起一个进程,保存其机器状态,并用另一个进程先前保存的状态替换它的机器状态——唯一的区别是同一进程的两个线程共享相同的虚拟内存空间,使任务切换更加高效
多处理器系统上的多线程实际上要困难得多,因为您会遇到从多个CPU/内核同时访问内存的问题,以及由此产生的所有令人讨厌的内存同步问题。四核系统上可能有四个以上的活动线程。有调度,除非您可以保证进程不会尝试创建比处理器更多的线程 是的,在单核计算机上可以有多个线程 单处理器系统和多处理器系统之间的区别在于,多处理器系统一次确实可以做多件事情。它一次可以做N件事情,其中N是处理器核心的数量。单处理器核心一次只能做一件事。正如WhozCraig在评论中所说,这是实际并发和感知并发之间的区别 最近我在某个地方读到它,我可以在单线程上进行多线程处理 处理器系统。对吗?如果是,那么问题是什么 单处理器和多处理器系统之间的区别 是的,您可以在单处理器系统上执行多线程处理 在多处理器系统中,多个线程在不同的核上同时执行。 如果有两个线程和两个内核,那么每个线程将在单个内核上运行 在单处理器系统中,根据线程优先级和操作系统策略,多个线程一个接一个地执行,或等待一个线程完成或被操作系统抢占。但运行的线程会产生一种错觉,认为它们同时运行,相对于用户空间应用程序所需的应用程序响应时间 时间比较(示例): 如果两个线程的执行时间各为10us,那么在2处理器系统上,净时间为10us
如果两个线程的执行时间各为10us,那么在单处理器系统上,净时间为20us。它实际上是我正在构建的一个程序的原型。它是在一个线程中实现协作多任务
main
只需将quit
标志设置为false,并填充函数指针数组(任务),然后调用loop
loop
使用setjmp
为非本地跳转(从函数跳转回执行中的前一个位置)设置返回点,然后继续调用第一个任务(函数)
每个任务都以yield()
结束。也就是说,没有一个任务函数实际返回。它们不仅不包含返回代码>语句(这很好,因为它们是void
函数,即过程),但它们不会到达返回
,即使它在那里,因为yield
跳回setjmp
调用,这一次在循环中为if
语句生成1。由if
语句控制的语句在重新进入while
循环之前选择不同的任务
因此,每个任务函数都会运行多次,并让调度器(即if(setjmp…
语句))选择要运行的新任务
#include <stdio.h>
#include <setjmp.h>
jmp_buf dispatch;
int ntasks;
void (*task[10])(void);
int quit;
void yield(void) {
longjmp(dispatch, 1);
}
void loop() {
static int i = 0;
if(setjmp(dispatch))
i = (i+1) % ntasks;
while(!quit)
task[i]();
}
int acc = 0;
void a(void) {
if (acc > 10) quit = 1;
printf("A\n");
yield();
}
void b(void) {
acc *= 2;
printf("B\n");
yield();
}
void c(void) {
acc += 1;
printf("C\n");
yield();
}
int main() {
quit = 0;
ntasks = 3;
task[0] = a;
task[1] = b;
task[2] = c;
loop();
return 0;
}
#包括
#包括
jmp_buf调度;
int ntasks;
作废(*任务[10])(作废);
退出;
空隙率(空隙){
longjmp(调度,1);
}
void loop(){
静态int i=0;
if(setjmp(调度))
i=(i+1)%n任务;
而(!退出)
任务[i]();
}
int acc=0;
无效a(无效){
如果(acc>10)退出=1;
printf(“A\n”);
收益率();
}
无效b(无效){
acc*=2;
printf(“B\n”);
收益率();
}
无效c(无效){
acc+=1;
printf(“C\n”);
收益率();
}
int main(){
退出=0;
ntasks=3;
任务[0]=a;
任务[1]=b;
任务[2]=c;
loop();
返回0;
}
本例与单处理机多任务计算机系统的区别在于,实际处理机支持在执行过程中中断任务并从同一地点恢复它。在任务模拟为单个功能的C仿真中,这是不可能的。然而,任务可以由C函数序列组成。每个函数都会向调度程序(可能是一个函数指针数组,或者是一个链表)提供的变量。
是的,您完全可以。
很久以前(Win95?)我们从协作式多任务处理转向多线程处理,因为总是有人把协作部分搞砸了。
计算机上的每一个程序都至少有一个线程。可能更多。CPU每秒疯狂地在这些线程之间切换数百万次。如果它们都没有任何事情可做,它甚至可能会闲置一段时间
多核系统只意味着其中两个或多个线程可能并行运行
然而,它给你带来的事情要少得多