2012-11-03 18 views
2

我在寫一個具有事件隊列的應用程序。我的目的是以這樣的方式創建它,即多個線程可以寫入,並且一個線程可以從隊列中讀取,並將處理彈出的元素移交給另一個線程,以便後續的彈出不會被阻止。我用了一個鎖,推,然後從彈出隊列項的條件變量:併發訪問一個隊列(多個生產者和消費者)問題 - C++,Boost

void Publisher::popEvent(boost::shared_ptr<Event>& event) { 

    boost::mutex::scoped_lock lock(queueMutex); 
    while(eventQueue.empty()) 
    { 
     queueConditionVariable.wait(lock); 
    } 
    event = eventQueue.front(); 
    eventQueue.pop(); 
    lock.unlock(); 
} 

void Publisher::pushEvent(boost::shared_ptr<Event> event) { 

    boost::mutex::scoped_lock lock(queueMutex); 
    eventQueue.push(event); 
    lock.unlock(); 
    queueConditionVariable.notify_one(); 

} 

在Publisher類(只創建一個實例)的構造,我開始一個線程將通過一個迭代循環,直到一個notify_one()被捕獲,然後被啓動另一個線程來處理該事件從隊列中彈出:

在構造:

publishthreadGroup = boost::shared_ptr<boost::thread_group> (new boost::thread_group()); 
publishthreadGroup->create_thread(boost::bind(queueProcessor, this)); 

queueProcessor方法:

void queueProcessor(Publisher* agent) { 

while(true) { 
    boost::shared_ptr<Event> event; 
    agent->getEvent(event); 
    agent->publishthreadGroup->create_thread(boost::bind(dispatcher, agent, event)); 

    } 
} 

並且在調度方法中,完成相關處理,並且經處理的信息通過節儉發佈到服務器。在程序存在的另一個方法中,它存在於主線程中,我調用join_all()以便主線程等待線程完成。

在這個實現中,在調度器的線程被創建後,在上面的while循環中,我遇到了死鎖/掛起。運行的代碼似乎被卡住了。這個實現有什麼問題?是否有更乾淨,更好的方式來做我想做的事情? (多個生產者和一個消費者線程遍歷隊列並將元素的處理交付給不同的線程)

謝謝!

+0

你能發佈完整的例子嗎? –

+0

我假設在你的'queueProcessor'方法中你打算調用'agent-> popEvent(event)'而不是'agent-> getEvent(event)'。 – aldo

回答

1

看來,queueProcessor函數將永遠運行,並且運行它的線程永遠不會退出。由該函數創建的任何線程都將執行它們的工作並退出,但此線程(在publishthreadGroup中創建的第一個線程)具有無法停止的while(true)循環。因此致電join_all()將永遠等待。你可以創建一些其他標誌變量觸發該函數退出循環並返回?這應該夠了吧!