使用boost::asio定时器进行线程安全工作

Thread safe work with boost::asio timers

本文关键字:线程 安全 工作 定时器 boost asio 使用      更新时间:2023-10-16

我有一个关于boost asio定时器和使用它们的安全线程的问题。比方说,我有以下课程:

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

您很少想使用io_service::stop((

几点:

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

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

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