2017-10-12 36 views
1

所以我有这个while循环,做了一些工作,多线程,我想,只要所有线程正在它的工作,是这样的:Ç - 并行线程的条件变量

while(*threads are working*) { 
pthread_mutex_lock 
if(stack is not empty) { 
    pthread_cond_broadcast 
    *critical work* 
    pthread_mutex_unlock 
} 
else { 
    pthread_cond_wait 
    pthread_mutex_unlock 
} 

我基本上要这个while循环运行,直到所有线程都检查了堆栈是否为空并且在else情况下等待。所有提示都非常欢迎,谢谢。

+0

您的示例代码会序列化您的所有线程,因为'* critical work *'正在被锁定的互斥锁下执行。这种做法首先破坏了使用多个线程的目的。这是故意的吗?从你写的内容来看,你可能希望让所有的线程都并行执行,然后只在最后进行同步,以确保所有线程在继续之前完成。那是对的吗? – ComicSansMS

+1

我想让线程并行执行,然后当共享堆栈为空,并且每个线程都没有任何东西推入堆栈时,我希望循环停止。该程序应搜索具有特定名称的所有文件并打印出路径,堆栈包含未检查过的文件夹 – Frans

回答

1

请记住,条件变量只是表示封闭程序中的某些条件已发生变化。使用条件变量时最重要的是要了解条件是什么,并确保它的建模正确。该条件通常也被称为谓词

在你的情况下,你的线程作为共享堆栈上的工作的生产者和消费者。如果线程不工作,它将进入等待状态,只有满足以下条件之一时才会返回:

  • 某些其他线程将在堆栈上工作。在这种情况下,您希望自己的线程醒来以帮助完成新推送的工作。
  • 所有线程都进入等待状态。在那种情况下,没有更多的工作要做,因为所有的线程都完成了,所有的工作都不会再被压入堆栈。

这两个条件的分离构成谓词。

第一个条件已经在程序中建模,因为您可以简单地检查堆栈以确定是否有新工作可用。然而第二个条件不是。您无法检查当前有多少个线程处于等待状态。

解决方案是该条件也,这是很容易通过引入一个计数器进行建模:

int threads_waiting = 0; 
while(true) { 
    pthread_mutex_lock 
    if(stack is not empty) { 
    *critical work* 
    if(i_pushed_some_work_on_the_stack) { 
     pthread_cond_broadcast // wake up any threads that have gone to sleep 
           // because the stack ran out of work 
    } 
    pthread_mutex_unlock 
    } else { 
    ++threads_sleeping 
    if(threads_sleeping == number_of_threads) { 
     pthread_cond_broadcast  // wake up any threads waiting for 
           // the last thread to finish     
     pthread_mutex_unlock  // ... and we're done! 
     return 
    } 
    while(true) { 
     pthread_cond_wait 
     if(stack is not empty) { 
     // there is more work available; continue outer loop 
     --threads_sleeping 
     break; 
     } else if(threads_sleeping == number_of_threads) { 
     // everybody is done, so let's return 
     pthread_mutex_unlock 
     return 
     } else { 
     // spurious wakeup; go back to sleep 
     } 
    } 
    pthread_mutex_unlock 
} 

注意我们如何调用pthread_cond_broadcast每当谓语变化和从pthread_cond_wait回国后,我们检查封闭条件找出下一步该做什么。

+0

谢谢,您的示例给了我一个关于如何解决它的好主意! – Frans