当一个线程已经在超时处理程序中时,在上下文切换期间销毁截止时间计时器会发生什么?
例如,如果在执行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()
}
}
答案 0 :(得分:0)
如果在多线程环境中删除一个线程中的对象,而另一个线程使用它,则可能会出现崩溃,完全如您所见。
当使用boost :: asio时,如果你取消定时器,你仍然必须让它执行处理程序(这会得到一个操作被取消的错误),然后才能安全地销毁对象。根据您的其他设置,有一些方法。手动使用同步灵活性,使用boost::asio::strand
将某些交互限制到单个线程,或使用boost::shared_ptr
确保密钥对象在不再被引用之前保持可用。
如果没有更多信息,很难告诉您最好的选择。