2012-10-24 59 views
2

當一個線程已經在超時處理程序中時,在上下文切換期間銷燬截止時間定時器會發生什麼情況?當超時處理程序中的boost deadline_timer被破壞時會發生什麼情況

例如,如果在執行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-> Execute()時出現了分段錯誤。 GDB分析顯示mCommand無效。可能從另一個線程中刪除。 謝謝。

編輯:

爲什麼不以下更改解決這個問題?

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

回答

0

如果在多線程環境中,你在一個線程中刪除的對象,而使用它另一個,你可以得到一個崩潰,正如你所看到的。

當使用boost :: asio時,如果取消定時器,在安全地銷燬對象之前,仍然必須讓它執行處理程序(會得到一個操作被取消的錯誤)。根據您的其他設置,有一些方法。手動使用同步主體,使用boost::asio::strand將某些交互限制爲單個線程,或使用boost::shared_ptr確保關鍵對象在不再被引用前保持可用。

沒有更多的信息,很難告訴你最好的選擇。

+0

如果mTimer.cancel()是從一個線程調用的,而另一個線程已經在TimerCallback方法中,我希望boost會阻塞(可配置選項)。使用互斥鎖解決它。使用weak_ptr處理更乾淨的解決方案。歡迎提出建議! – yaronkle

+0

爲什麼不能工作:if(mTimer.cancel()== 0){mTimer.wait()} – yaronkle

相關問題