我有點卡住了這個問題,所以這是我的呼救聲。死鎖與提升:: condition_variable
我有一個管理器將某些事件推送到隊列中,這是在另一個線程中進行的。 我不希望此線程在隊列中的事件「忙於等待」,因爲它可能一直爲空(以及它可能始終爲滿)。 另外,我需要m_bShutdownFlag
來在需要時停止線程。 所以我想嘗試一下condition_variable
這種情況:如果有東西被推到隊列中,那麼線程就開始工作。
簡化代碼:
class SomeManager {
public:
SomeManager::SomeManager()
: m_bShutdownFlag(false) {}
void SomeManager::Initialize() {
boost::recursive_mutex::scoped_lock lock(m_mtxThread);
boost::thread thread(&SomeManager::ThreadProc, this);
m_thread.swap(thread);
}
void SomeManager::Shutdown() {
boost::recursive_mutex::scoped_lock lock(m_mtxThread);
if (m_thread.get_id() != boost::thread::id()) {
boost::lock_guard<boost::mutex> lockEvents(m_mtxEvents);
m_bShutdownFlag = true;
m_condEvents.notify_one();
m_queue.clear();
}
}
void SomeManager::QueueEvent(const SomeEvent& event) {
boost::lock_guard<boost::mutex> lockEvents(m_mtxEvents);
m_queue.push_back(event);
m_condEvents.notify_one();
}
private:
void SomeManager::ThreadProc(SomeManager* pMgr) {
while (true) {
boost::unique_lock<boost::mutex> lockEvents(pMgr->m_mtxEvents);
while (!(pMgr->m_bShutdownFlag || pMgr->m_queue.empty()))
pMgr->m_condEvents.wait(lockEvents);
if (pMgr->m_bShutdownFlag)
break;
else
/* Thread-safe processing of all the events in m_queue */
}
}
boost::thread m_thread;
boost::recursive_mutex m_mtxThread;
bool m_bShutdownFlag;
boost::mutex m_mtxEvents;
boost::condition_variable m_condEvents;
SomeThreadSafeQueue m_queue;
}
但是,當我有兩個(或更多)幾乎同時呼叫測試,以QueueEvent
,它在該行boost::lock_guard<boost::mutex> lockEvents(m_mtxEvents);
被鎖定,直到永遠。
似乎第一個電話永遠不會釋放lockEvents
,所以其餘的只是等待其釋放。
請幫我找出我做錯了什麼,以及如何解決這個問題。
謝謝,我已修復#1和#2。我的問題的原因是在隊列元素的處理中。由於處理過程中的'while'週期不好,有幾個元素永遠持續處理。 – Ganya