当boost deadline_timer在超时处理程序中被破坏时会发生什么

时间:2012-10-24 21:16:19

标签: c++ boost boost-asio

当一个线程已经在超时处理程序中时,在上下文切换期间销毁截止时间计时器会发生什么?

例如,如果在执行TimerCallback期间上下文切换到另一个线程删除了ScheduledCommand?

ScheduledCommand::ScheduledCommand(
        const boost::shared_ptr<CommandInterface> command,
        const boost::posix_time::time_duration timeTillExecution):
    mTimer(TheCommandTimerThread::instance()->IoService(), timeTillExecution),
    mCommand(command)
{
    mTimer.async_wait(boost::bind(&ScheduledCommand::TimerCallback,
                                  this,
                                  boost::asio::placeholders::error));
}

ScheduledCommand::~ScheduledCommand()
{
    Cancel();
}

void ScheduledCommand::TimerCallback(const boost::system::error_code& error)
{
    if (!error)
    {
        assert(mCommand);
        mCommand->Execute();
    }
}

以上代码在mCommand-&gt; Execute()处有分段错误。 GDB分析显示mCommand无效。可能从另一个线程中删除。 感谢。

编辑:

为什么以下更改无法解决此问题?

ScheduledCommand::Cancel()
{
    if (mTimer.cancel() == 0) 
    { 
        mTimer.wait() 
    } 
}

1 个答案:

答案 0 :(得分:0)

如果在多线程环境中删除一个线程中的对象,而另一个线程使用它,则可能会出现崩溃,完全如您所见。

当使用boost :: asio时,如果你取消定时器,你仍然必须让它执行处理程序(这会得到一个操作被取消的错误),然后才能安全地销毁对象。根据您的其他设置,有一些方法。手动使用同步灵活性,使用boost::asio::strand将某些交互限制到单个线程,或使用boost::shared_ptr确保密钥对象在不再被引用之前保持可用。

如果没有更多信息,很难告诉您最好的选择。