【问题标题】:pthreads and concurrencypthreads和并发
【发布时间】:2013-02-02 03:51:59
【问题描述】:

我有以下代码:

#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 次,反之亦然。字符串不应该像这里一样交替显示而不是连续显示吗?

【问题讨论】:

    标签: c multithreading concurrency pthreads


    【解决方案1】:

    另外两个答案是正确的,但我想补充一下:

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

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

    【讨论】:

      【解决方案2】:

      调度程序在时隙中运行进程。时隙足够大以提高效率,但又足够小以产生同时执行的错觉。

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

      最重要的是,输出有时会被缓冲,因为执行一次大写入所需的处理能力与执行一次小写入所需的处理能力大致相同。当输出到交互式终端设备时,大多数系统都会禁用缓冲,但现在您的环境细节开始变得非常重要。

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

      毕竟,您一次只创建一个,而一个总是准备好在另一个之前运行。

      【讨论】:

        【解决方案3】:

        调度程序交错线程的顺序不是确定性的(……嗯,但仅从调度程序/内核的角度来看)。您不应该对订单做出假设。

        这种情况中,您会体验到任何一个线程都可以在调度程序之前完成它们的全部工作 -> 抢占它并允许另一个线程运行。

        【讨论】:

          猜你喜欢
          • 2018-12-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多