3

我目前正在将处理程序发布到我的 io_service 并在线程池中执行它们。

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();

到目前为止一切顺利,但现在我想在处理程序队列为空时触发一个事件,而不会杀死我的活动(但正在等待)线程。

有可能吗?怎么做?

4

1 回答 1

3

我第一次看到使用asio作为队列调度程序。我认为不错的技术。

好吧,我建议您运行io_service::run来为处理程序提供服务。如文档所述,run将阻塞,直到 io_service 停止或所有工作完成。所以你可以在io_service::run之后运行你的“空队列事件” :

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

如果您在此 io_service 上没有其他 asio 活动并且您没有使用 io_service::work。

正如评论中提到的,您使用io_service::work所以计划 A 失败(它不会工作,因为此类阻止退出空队列)。好吧,您可以io_serv.post()在每束io_serv.post()-s 之后执行线程作业。处理程序可以在其他线程完成工作时使用boost::condition包含等待。正如您post()在实际工作之后为此所做的那样,我认为 asio 会在调度所有工作后调用它,但它的主题有待调查。无论如何,post()如果条件尚未准备好,该处理程序可以重新释放当前线程。

但我认为最简单的方法是将io_service::work替换为 equialent while构造。

于 2012-11-22T17:42:39.333 回答