Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 多线程可以在单处理器系统上实现吗?_C_Windows_Multithreading_Winapi - Fatal编程技术网

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每秒疯狂地在这些线程之间切换数百万次。如果它们都没有任何事情可做,它甚至可能会闲置一段时间

多核系统只意味着其中两个或多个线程可能并行运行

然而,它给你带来的事情要少得多