0

我有一个关于 boost 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 函数可以在析构函数之后调用,我们会崩溃。

4

2 回答 2

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 将从多个线程中使用,您需要使用互斥锁来管理访问。

只是几点。不会为您重写代码。

于 2013-03-25T11:43:36.247 回答
1

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

于 2013-03-25T13:08:17.807 回答