【问题标题】:Concurrency in Threads线程中的并发
【发布时间】:2011-11-02 09:33:55
【问题描述】:

我明天有一个关于操作系统的考试。我对前一年的几个问题有疑问....我不擅长 C

解释为什么下面的代码不是最适合并发的。以及如何优化代码..

void * func ( void * arg) 
{ 
printf("printing from thread %d\n",(int) arg); 
return null;
}
int main(void) 
{ 
    pthread_t threads[5];
    int i;
    for(i=0;i<5;i++)
    {
          pthread_create( &(thread[i]), NULL, func, (void*) i);
          pthread_join( threads[i], NULL);
    } 
 return 0;
}

第二个....

非常感谢任何帮助.....

【问题讨论】:

    标签: c concurrency pthreads


    【解决方案1】:

    在第一个 sn-p 中,您不应该加入 for。在创建后立即加入将防止并发:基本上您在任何时候都只有一个线程并且您正在等待它。改为加入外部:

    for(i = 0; i<5; i++)
          pthread_create(&thread[i], NULL, func, (void*) i);
    
    for(i = 0; i < 5; i++)
          pthread_join(threads[i], NULL);
    

    编辑(感谢 R..)

    第三次查看第二个 sn-p 很明显会发生以下情况:

    • 父级尝试锁定互斥锁,向子级发出信号,然后继续解锁并加入。但是孩子没有等待条件变量,信号丢失了。
    • 孩子最终锁定互斥锁并开始等待。

    由于无法取得进展,因此陷入僵局。

    【讨论】:

    • 你对第二个sn-p的分析是错误的。 pthread_cond_wait 解锁互斥锁。问题是反过来的:如果父母先获得锁,信号将丢失,孩子将永远等待。这就是为什么您需要在创建孩子之前锁定互斥锁。
    • @R.. 没错,pthread_cond_wait 解锁了互斥锁 - 我编辑了我的答案。但是在启动子线程之前加锁基本会保证第一个信号丢失,不是吗?
    • 是的,好点。这就是为什么正确使用条件变量总是需要检查谓词。没有一个就没有正确的方法来使用它们。如果您想要纯信号,信号量,而不是 cond var,是正确使用的同步对象。
    【解决方案2】:

    对于第一个问题,您不要启动五个线程同时运行,而是创建一个线程并等待它退出,然后再启动下一个。

    对于第二个问题,想想如果线程在主函数执行之前先锁定互斥体会发生什么。

    【讨论】:

    • 线程先锁没问题。主要是先锁定它,这是有问题的。
    猜你喜欢
    • 1970-01-01
    • 2016-05-21
    • 1970-01-01
    • 2014-06-30
    • 2018-03-08
    • 1970-01-01
    • 1970-01-01
    • 2012-11-12
    • 1970-01-01
    相关资源
    最近更新 更多