提升asio异步等待条件变量

时间:2011-07-21 12:16:25

标签: c++ pthreads boost-asio boost-thread concurrent-programming

是否可以对boost :: asio中的条件变量执行异步等待(读取:非阻塞)?如果不直接支持任何提示,将不胜感激。

我可以实现一个计时器,甚至每隔几毫秒启动一次唤醒,但这种方法非常低劣,我发现很难相信条件变量同步没有实现/记录。

2 个答案:

答案 0 :(得分:7)

如果我正确理解了intent,你想在asio线程池的上下文中发出一个事件处理程序,当一些条件变量被发出信号时?我认为在处理程序的开头等待条件变量就足够了,而io_service::post()本身最后会回到池中,这类似的东西:

#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
boost::asio::io_service io;
boost::mutex mx;
boost::condition_variable cv;
void handler()
{
    boost::unique_lock<boost::mutex> lk(mx);
         cv.wait(lk);
    std::cout << "handler awakened\n";
    io.post(handler);
}
void buzzer()
{
    for(;;)
    {
        boost::this_thread::sleep(boost::posix_time::seconds(1));
        boost::lock_guard<boost::mutex> lk(mx);
            cv.notify_all();
    }
}
int main()
{
    io.post(handler);
    boost::thread bt(buzzer);
    io.run();
}

答案 1 :(得分:0)

我可以建议基于 boost::asio::deadline_timer 的解决方案,这对我来说很好用。这是 boost::asio 环境中的一种异步事件。 一件非常重要的事情是,'handler' 必须通过与 'cancel' 相同的 'strand_' 序列化,因为从多个线程使用 'boost::asio::deadline_timer' 不是线程安全的。

class async_event
{
public:
    async_event(
        boost::asio::io_service& io_service,
        boost::asio::strand<boost::asio::io_context::executor_type>& strand)
            : strand_(strand)
            , deadline_timer_(io_service, boost::posix_time::ptime(boost::posix_time::pos_infin))
    {}

    // 'handler' must be serialised through the same 'strand_' as 'cancel' or 'cancel_one'
    //  because using 'boost::asio::deadline_timer' from multiple threads is not thread safe
    template<class WaitHandler>
    void async_wait(WaitHandler&& handler) {
        deadline_timer_.async_wait(handler);
    }
    void async_notify_one() {
        boost::asio::post(strand_, boost::bind(&async_event::async_notify_one_serialized, this));
    }
    void async_notify_all() {
        boost::asio::post(strand_, boost::bind(&async_event::async_notify_all_serialized, this));
    }
private:
    void async_notify_one_serialized() {
        deadline_timer_.cancel_one();
    }
    void async_notify_all_serialized() {
        deadline_timer_.cancel();
    }
    boost::asio::strand<boost::asio::io_context::executor_type>& strand_;
    boost::asio::deadline_timer deadline_timer_;
};