pthreads和并发性

3
我有以下代码:

我有以下代码:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#define LOOPS 10000

void *run(void *arg)
{
    int id = strtol(arg,NULL,0);
    int i;
    for(i=0; i<LOOPS; i++)
    {
        printf("In %d.\n",id);
    }
}

int main()
{
    pthread_t p1,p2;
    void *res;

    pthread_create(&p1,NULL,run,"1");
    pthread_create(&p2,NULL,run,"2");
    pthread_join(p1,&res);
    pthread_join(p2,&res);
    return 0;
}

当我运行这段代码时,要么字符串 "In 1" 连续显示 10000 次,然后字符串 "In 2" 连续显示 10000 次,要么反过来。按理说,这些字符串应该是交替显示的,而不是像这里一样连续显示。请问这是否正常?
3个回答

8

线程被调度程序交错的顺序不是确定性的(... 从调度程序/内核的角度来看,它是确定性的)。您不应该对顺序做出任何假设。

在这种情况下,您会发现其中一个线程被允许在调度程序->抢占之前完成其全部工作,然后允许另一个线程运行。


2

调度程序在时间片中运行进程。时间片足够大以提高效率,但足够小以产生并发执行的假象。

在多核CPU上,实现在操作系统内核级别的线程实际上会并行执行。

此外,输出有时会被缓冲,因为进行一次大型写入和进行一次小型写入需要大约相同的处理能力。当输出到交互式终端设备时,大多数系统都会禁用缓冲,但是这时您的环境细节开始真正起作用。

要使输出交错,它必须是未缓冲的,并且运行在一个既是多核的调度程序,又是异常精细的并愿意进行昂贵的上下文切换的调度程序上,仅因为您生成了一行输出。如果是多核的话,库和内核的执行路径必须在三个核心上巧合平衡。这可能永远不会发生。

毕竟,您一个接一个地创建,其中一个总是准备好在另一个之前运行。


2
其他两个答案是正确的,但我想补充一下:这两个输出确实是交错的。它们只是不是每一行或每两行交错,而更可能是数千行。当每个线程被赋予时间量子时,它有时间输出数千行。由于您在每个线程上仅打印10k行,因此一个线程在另一个线程开始之前就有时间完成其工作。尝试用无限循环替换您的for循环,并观察会发生什么。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接