2012-07-02 37 views
3

我有一个工作线程处理工作项的队列。工作项目现在可能无法处理,因此工作线程可能会将他们推回到队列中。在两种不同条件下的pthread同步

void* workerFunc(void* arg) { 
    WorkItem* item = NULL; 

    while(true) { 
     { 
      scoped_lock(&queueMutex); 
      while(workerRunning && workQueue.empty()) 
       pthread_cond_wait(&queueCondition, &queueMutex); 
      if(!workerRunning) 
       break; 

      item = workQueue.front(); 
      workQueue.pop(); 
     } 

     // process item, may take a while (therefore no lock here), 
     // may also be considered unprocessable 

     if(unprocessable) { 
      scoped_lock(&queueMutex); 
      workQueue.push(item); 
     } 
    } 
    return NULL; 
} 

现在我需要做到以下几点:不时,我需要通过工作队列进行扫描以删除不再需要的(从入队的工作项目在同一个线程)的项目。我无法为此使用queueMutex,因为我可能会错过当前正在处理的项目,所以我需要一种方法来暂停整个处理线程,所有撤消的项目实际上都在队列中(最好在右上角while循环)。

我想到了第二个bool变量(“paused”)与另一个互斥体和条件变量的组合,但接下来是工作人员正在等待queueCondition上的信号的特殊情况;实际上,pthread_cond_wait()调用将不得不解锁/锁定这两个互斥锁。

我想这个问题一定有一个简单的解决方案,但我似乎无法想出它 - 我希望你们中的一些人能够帮助我。

非常感谢。

+1

如果生产者(该线程也插入项目)将会从队列中删除不必要的项目 - 它应该获取相同的互斥体('queueMutex') - 因为它是修改队列。处理器线程是否刚刚将一个项目从队列中弹出并对其进行处理并不重要 - 如果未处理,则下一次生产者扫描队列中的不必要项目时,它将选择该项目。 – Nim

+0

为什么条件在队列不空时等待? – jxh

+1

哦,这是一个错字,我会修好它,对不起。 – Pontomedon

回答

4

基本上你需要在POSIX上模拟WinAPI的WaitForMultipleObjects()调用。与WinAPI一样,POSIX没有一个API来等待所有类型的事件/对象。使用pthread_cond_timedwaitclock_gettime。您可以参考此文件WaitFor API了解许多实施细节。

这里有一些有趣的代码(太多可以发布在答案中,但可用),可以解决您的问题。

P.S.参考这个问题的讨论:WaitForSingleObject and WaitForMultipleObjects equivalent in linux

+1

非常感谢,我会尽力 – Pontomedon

+0

不客气。所以接受的答案:) –