2014-10-29 119 views
2

我有問題習慣了線程編程。我試圖用互斥和鎖構建一個構造。但我需要boost :: condition_variable :: wait兩個鎖作爲參數。但是沒有兩個鎖的等待功能。boost condition_variable等待多個鎖

有沒有人給我提示,或者我的方法完全錯誤?

我的目標是

  • 允許同時添加(),全部寫入緩衝區
  • 工作者線程運算符()(),存儲緩衝值
  • 和搜索(),等待在搜索之前的工作線程


    class Archive 
    { 
     vector externalBuffer; 
     vector swapBuffer; 
     vector internalBuffer; 
     boost::mutex externalBufferMutex; 
     boost::mutex allBufferMutex; 
     boost::condition_variable bufferIsFilledConditionVariable; 

     void operator()() 
     { 
      unique_lock allBufferLock(allBufferMutex); 
      while(true) 
      { 
       { 
        unique_lock lock(externalBufferMutex); 
        while(buffer.empty()) 
        { 
         bufferIsFilledConditionVariable.wait(...); // I should call it with two locks? 
        } 
        externalBuffer.swap(swapBuffer); 
       } 

       { 
        internalBuffer.swap(swapBuffer); 
        // store values from internalBuffer 
        ... 
        internalBuffer.clear(); 
       } 
      } 
     } 

     void add(value) // pseudo code here 
     { 
      { 
       lock_guard lock(externalBufferMutex); 
       externalBuffer.push_back(value); 
      } 
      bufferIsFilledConditionVariable.notify_one(); 
     } 

     // search will not be used concurrently with add() 
     // it should just wait for the worker thread 
     someReturnValue search() 
     { 
      unique_lock lock(allBufferMutex); 
      // search here 
      ... 
     } 

    } 

+0

請詳細說明你的問題:是什麼內部緩衝區發生?它被搜查?何時和誰使用內部緩衝區中的數據?爲什麼你需要3個緩衝區?它提醒了古典生產者/消費者模式,除非我們沒有看到消費者 – 2014-10-29 11:03:32

回答

0

您可以手動之前調用allBufferLock.unlock之後的和lock。但請注意,多個互斥鎖的嵌套鎖可能很容易導致死鎖,如果在其他地方他們也會被鎖定。在獲取另一個之前解鎖一個將是更安全的,例如,如果可能的話,有internalBufferLock而不是allBufferLock

1

我不確定你要達到什麼目標,一般來說,你應該避免在多重重疊的鎖下操作。

但是,一般來說,爲了避免死鎖,您只需使用一致的鎖定順序。非會員lock功能可以提供幫助的:

unique_lock lk_all(allBufferMutex,  boost::defer_lock); 
unique_lock lk_ext(externalBufferMutex, boost::defer_lock); 
boost::lock(lk_all, lk_ext); 

while(internalBuffer.empty()) 
{ 
    lk_all.unlock(); 
    bufferIsFilledConditionVariable.wait(lk_ext); 
    boost::lock(lk_all, lk_ext); 
} 

這是未經測試,但是可以幫助你對你的方式