2012-11-22 51 views
2

我目前正在將處理程序發佈到我的io_service並在線程池中執行它們。Boost Asio - 如何知道處理程序隊列何時爲空?

io_serv.post(boost::bind(&Class::bar, p1, p2)); 

我的工人運行此功能:

m_mutex.lock(); 
std::cout << "[" << boost::this_thread::get_id() 
     << "] Thread Start" << std::endl; 
m_mutex.unlock(); 

size_t tasks = m_serv.run(); 

m_mutex.lock(); 
std::cout << "[" << boost::this_thread::get_id() << "] accomplished " 
      << tasks << " tasks" << std::endl; 
m_mutex.unlock(); 

到目前爲止好,但現在我希望在處理隊列爲空不殺死我的積極的(但等待)線程觸發一個事件。

這是可能的和如何?

+0

您的任務是否正在進行異步等待,導致它們不能立即處理? (類似於'async_receive'?) – Chad

+0

不,他們完成他們的工作,通過隊列中的信號發佈新事件。一切完成後,所有線程都在等待。 – Kikohs

+0

您可以保留處理程序發佈/執行的次數嗎?看到我的答案(對我的問題)在這裏:http://stackoverflow.com/questions/12166513/boostasio-thread-pools-and-thread-monitoring – Chad

回答

2

我第一次看到使用asio作爲隊列調度器。我認爲不錯的技術。

嗯,我建議你運行io_service ::運行服務處理程序。由於documentation說,運行將阻塞,直到io_service停止或所有工作已完成。所以,你可以以後io_service對象運行「空隊列事件」 ::運行

while(!finished) { 
    io_serv.run(); 
    io_serv.reset(); 
    io_serv.post(boost::bind(&Class::fill_queue, instance)); 
} 

此情況下,你對這個io_service對象沒有其他ASIO活動,您不使用io_service對象::工作。

正如您在使用io_service :: work所述的評論中提到的那樣,計劃A失敗(因爲此類阻止在空隊列上退出,所以它不起作用)。那麼,您可以在線程作業的每個io_serv.post() -s之後執行io_serv.post()。處理程序可以包含等待boost :: condition,而其他線程完成其工作。正如你在實際工作之後爲此做了post(),我認爲阿西奧在派遣所有工作後會調用它,但它的調查對象。無論如何,如果條件還沒有準備好,那麼處理程序可以自己重置post()以釋放當前線程。

但我認爲最簡單的方法是用equialent 結構來代替io_service對象::工作

+0

我的處理程序正在隊列中發佈新事件,所以最後的空作業實際上不是最後一個。 – Kikohs

+0

使用您的解決方案,在每個循環中,我將被迫啓動新線程,因爲它們會在先前的io_serv.run()之後死亡。 – Kikohs

+0

不,你在每個線程中運行'io_serv.run()'。使用** strand **來防止'fill_queue'同時運行。你不在'post()'處理程序中創建新的線程,對吧?否則它不是線程池) – PSIAlt

相關問題