pthreads和并发

时间:2013-02-17 17:46:21

标签: c multithreading concurrency pthreads

我有以下代码:

#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 个答案:

答案 0 :(得分:8)

调度程序交叉线程的顺序不是确定性的(......它只是从调度程序/内核的角度来看)。你不应该对订单做出假设。

这种情况下你会遇到其中一个线程被允许在调度程序之前完成整个工作 - &gt;抢占它并允许另一个线程运行。

答案 1 :(得分:2)

计划程序在时间段中运行进程。时间段足够大,效率高但足够小,可以产生同时执行的错觉。

在多核CPUS上,在OS内核级实现的线程实际上将并行执行。

除此之外,输出有时是缓冲的,因为执行一次大写操作需要大约相同的处理能力才能执行一次小写操作。当输出到交互式终端设备时,大多数系统都禁用缓冲,但现在环境的细节真的很重要。

对于要交错的输出,它必须是无缓冲的并且在调度程序上运行,该调度程序要么是多核的,要么是非常细粒度的,并且只是因为您生成了一行输出而愿意进行昂贵的上下文切换。如果是多核,那么通过库和内核的执行路径必须在三个核心上巧合地平衡。这可能永远不会发生。

毕竟,你一次创建一个,一个将始终准备好在另一个之前运行。

答案 2 :(得分:2)

其他两个答案是正确的,但我想补充一点:

两个输出 交错。它们不是每一行或两行交错,而是更多可能是数千行。当每个线程被给予一定量的时间时,它有时间输出数千行。由于您只在每个线程上打印10k行,因此有一个人有时间在另一个线程开始之前完成其工作。

尝试用无限循环替换你的for循环,并观察会发生什么。