2013-07-23 94 views
1

所以我想在自定義線程上用C++創建一個同步事件隊列。據我所知,boost :: asio :: strand是一個優秀的候選人,有一個轉折點:當調用asio :: run()時,它只會在隊列中有事件時運行。代碼:使用boost :: asio和strands的事件隊列:等待新事件

this->control_strand_.reset(new boost::asio::strand(control_io_service_)); 
control_thread_ = boost::thread(boost::bind(&boost::asio::io_service::run,&control_io_service_)); 
control_thread_.join(); 

立即返回。現在我可以去找Boost Asio - How to know when the handler queue is empty?的答案,但是它有一個while-loop-等待它。我寧願讓它更基於事件(也就是說,當隊列爲空時,等待「包裝」調用)。釷只有這樣我能想到這樣做是完全包住鏈類,有它觸發信號,每當「包裝」被稱爲(像,僞代碼)

//some member variables 
boost::condition_variable cond_var; 
boost::mutex mut; 
std::unique_ptr<boost::asio::strand> control_strand_; 
boost::asio::io_service control_io_service_ 
//while loop,running on event processing thread 
void MessageProcessor() 
{ 
    while (true) 
    { 
    { 
     boost::unique_lock<boost::mutex> lock(mut); 
     cond_var.wait(lock); 
    } 
    control_io_service_.run(); 
    } 
} 
//post call,from different thread 
template <typename Handler> 
void wrap(Handler hand) 
{ 
    cond_var.notify_all(); 
    control_strand_->wrap(hand); 
} 

,這將永遠運行隊列不同時循環(我的同步是有點關閉,但這不是一個問題atm)。有更好,更標準的方法嗎?

+1

爲什麼你不能在'io_service :: work'對象中使用'io_service'? –

+0

@IgorR。男人,每當我嘗試做一些事情時,我都會遇到助推器庫完成它的問題,但我的搜索技巧似乎錯過了它。這看起來像是有效的。 (只需雙重檢查,這將是一個「隱含鏈」,即隊列是同步排空?)把它放在一個答案中,我會標記它。 – IdeaHat

回答

3

您可以直接使用io_service,它實現了「隱式鏈」。要保持運行狀態,只需給它io_service::work對象,如io_servicereference(請參閱「停止io_service不要用完工作」)。

請注意,io_service是故意線程安全的,因此您可以從外部線程post()函數。