线程安全工作与boost :: asio计时器

时间:2013-03-25 08:54:11

标签: c++ boost boost-asio

我有一个关于提升asio计时器和安全线程的问题。比方说,我有以下课程:

CTest.h:

class CTest
{
    boost::asio::io_service io;
    boost::asio::deadline_timer timer;

    void Check();
    CTest ();

    ~CTest ();
};

和CTest.cpp:

CTest::CTest():
timer (io, boost::posix_time::seconds(0))
{
    timer.async_wait(boost::bind(&CTest::Check, this));
    boost::thread t(boost::bind(&boost::asio::io_service::run, &io));
}

void CTest::Check()
{
    //some work

    m_timer.expires_from_now(boost::posix_time::seconds(10));
    m_timer.async_wait(boost::bind(&CTest::Check, this));

}

CTest::~CTest()
{
     io.stop();
}

那么,问题是如何完成Check thread安全?我的意思是,这个Check函数可以在析构函数之后调用,而且我们崩溃了。

2 个答案:

答案 0 :(得分:2)

使用io_service :: stop()很少是你想做的事。

几点:

  • 保持线程对象,并调用thread.join()以确保它已完成。
  • 不要调用io.stop(),调用m_timer.cancel()然后调用m_thread.join()进行清理。
  • 考虑使用shared_ptr和weak_ptr更干净地管理对象生存期(即:将weak_ptr实例绑定到async_wait回调而不是裸this。在回调函数中,将weak_ptr转换为shared_ptr,如果是有效然后调用方法。
  • m_timer将在多个线程中使用,您需要使用互斥锁管理访问。

只需几点。不会为你重写你的代码。

答案 1 :(得分:1)

你的析构函数应该停止所有计时器,因此在对象被销毁后不会被调用:m_timer.cancel()。此外,如果要阻止对同一对象的同时方法调用,请使用 boost :: asio :: strand :: wrap 包装 boost :: bind 。查看asio文档以获取示例。