使用boost :: asio和strand的事件队列:等待新事件

时间:2013-07-23 14:51:44

标签: c++ boost event-handling

所以我想在自定义线程上用c ++创建一个同步事件队列。据我所知,boost :: asio :: strand是一个非常好的候选者,有一个转折:当调用asio :: run()时,它只在strand的队列中有事件时运行。代码:

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循环等待。我宁愿让它更基于事件(也就是说,当队列为空时,等待“while”外观中的“wrap”调用)。我能想到这样做的唯一方法是完全包装strand类,让它在调用“wrap”时触发一个信号(比如伪代码)

//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);
}

这将在没有while循环的情况下永远运行队列(我的同步有点偏,但这不是问题atm)。是否有更好,更标准的方式?

1 个答案:

答案 0 :(得分:3)

您可以直接使用io_service,它实现“隐含链”。为了让它保持运行,只需给它io_service::work对象,就像在io_service reference中一样(参见“阻止io_service停止工作”)。

请注意,io_service是故意线程安全的,因此您可以从外部线程post()编写函数。