2014-01-13 18 views
0

所以我有這個代碼,它工作的很好,但在我看來,我鎖定了兩次,而且在我看來,如果第一個鎖被鎖定,我可以犯錯誤再次在第二個之前,有人能幫助我更好地理解在這種情況下使用獨特的鎖嗎?什麼是獨特的鎖和範圍鎖正在執行PrepDequeue函數?使用條件變量提升鎖定機制

m_mtx =可變的boost ::互斥

m_event =提振:: condition_variable

和enqueu和出隊的一些任意的隊列......

插入功能:

/** : */ 
void TaskImp::CmdsQueue::Enqueue(Command* cmd) 
{ 
    boost::mutex::scoped_lock guard(m_mtx); 
    bool signal = m_enqueue.empty(); 

    m_enqueue.push_back(cmd); 
    if (signal) { 
     m_event.notify_one(); 
    } 
} 

交換功能(所以出隊和入隊總是在不同的隊列上工作):

/** : */ 
void TaskImp::CmdsQueue::PrepDequeue(bool wait, size_t ms) 
{ 
    if (wait) { 
     //QueueingMutex_t dummy; once upon a time there was a dummy here 
     Timeout timeout(ms); 
     boost::unique_lock<boost::mutex> lock(m_mtx); // <=== what is it waiting for? 
     if (!m_event.timed_wait(lock, timeout, [this]() { 
      return !this ->m_enqueue.empty(); 
     })) { 
      return; 
     } 
    } 
    boost::mutex::scoped_lock guard(m_mtx); // safe lock? duplicated? 
    m_enqueue.swap(m_dequeue); 
} 

回答

0

拳我會盡量回答你的問題:

  1. PrepDequeue是瓦亭爲元素排隊,似乎wait == true當隊列爲空。

  2. 鎖是安全的,因爲前一個鎖超出了範圍。

現在我的想法:

的設計是不是安全,使用到隊列,好像他們是一個沒有意義的,只使用一個同步對象沒有意義或者使其同步。

更壞的是,有可能比運行PrepDequeue程序以外的其他線程,該線程可以在給Dequeue的調用來bloqued,但由於您使用的兩個隊列相同的同步對象,你可以結束了試圖從空隊列中的pop()

也好像Enqueue可能會喚醒PrepDequeue

我的建議是:

  1. 僅使用一個隊列
  2. Sycnhronize它
  3. PrepDequeue

你也可以看看這個實施獲取騎:concurrent_queue.hpp

+0

我會接受它,但如果仔細觀察,我正在使用2個隊列,並且只有1個線程是所以它實際上比一般的解決方案更好,並且當隊列WAS爲空時等待==真 – Alon