如何在多个线程中安全地使用提升截止时间计时器?

时间:2014-03-05 02:00:13

标签: c++ multithreading boost timer boost-asio

我像这段代码一样使用boost deadline_timer:

boost::asio::io_service g_io;
#define DEL(x) {delete x; x = NULL;}

void thr1()
{
    for(;;)
    {

         ...
        boost::asio::deadline_timer *t1 = new boost::asio::deadline_timer(g_io, boost::posix_time::seconds(60));
        t1->async_wait(boost::bind(&callback, boost::asio::placeholders::error, t1));

         ...
    }
}


void thr2()
{
    for(;;)
    {
           ....


        boost::asio::deadline_timer *t2 = new boost::asio::deadline_timer(g_io, boost::posix_time::seconds(60));
        t2->async_wait(boost::bind(&callback, boost::asio::placeholders::error, t2));

            ....
    }
}


void thr3()
{
    for(;;)
    {

         ....

        boost::asio::deadline_timer *t3 = new boost::asio::deadline_timer(g_io, boost::posix_time::seconds(60));
        t3->async_wait(boost::bind(&callback, boost::asio::placeholders::error, t3));

         ....
    }
}


void thr4()
{
    for(;;)
    {
         ....

        boost::asio::deadline_timer *t4 = new boost::asio::deadline_timer(g_io, boost::posix_time::seconds(60));
        t4->async_wait(boost::bind(&callback, boost::asio::placeholders::error, t4));

        ....
    }
}

void io_work()
{
    boost::asio::io_service::work work(g_io);
    g_io.run();
}


int main()
{
    boost::thread thread1(thr1);
    boost::thread thread2(thr2);
    boost::thread thread3(thr3);
    boost::thread thread4(thr4);

    boost::thread service_thread(io_work);

    thread1.join();
    thread2.join();
    thread3.join();
    thread4.join();

    service_thread.join();

    return 0;

}


void callback(const boost::system::error_code& e, boost::asio::deadline_timer *timer)
{
    if(e)
    {
        std::cout << "cancel" << std::endl;
    }
    else
    {
        std::cout << " time out occurred" << std::endl;

        if(timer->expires_at() <= boost::asio::deadline_timer::traits_type::now())
        {  
            if(timer) DEL(timer);
            return;
        }

        timer->expires_at(timer->expires_at()+boost::posix_time::seconds(1));
        timer->async_wait(boost::bind(callback, boost::asio::placeholders::error, timer));
    }
}

计时器运作良好。然而,当出现奇怪的错误时,我总是先怀疑我的asio代码,因为我找不到类似的asio代码。

没有任何互斥或同步,我可以在多个线程中注册计时器吗?

另外,如果您在mycode中发现任何问题,请告诉我。

感谢您的阅读。

2 个答案:

答案 0 :(得分:3)

截止日期计时器实例不是线程安全的。

单独的实例 线程安全。因此,要么使用单独的计时器,要么为访问添加同步。

文档链接:

答案 1 :(得分:1)

您应该注意到,callback函数将始终在调用io_service.run()的帖子中调用,在您的情况下为service_thread。 因此,您可以在没有同步的情况下访问两个线程上的计时器对象,如果没有同步,这是不安全的。

但具体情况取决于您的完整代码(...部分中的内容)。 如果您在示例中执行完全(仅在第一个线程中创建和启动计时器(保证在回调之前发生)并且仅在io_service线程中向后访问它应该是安全的