簡體   English   中英

在boost :: asio :: io_service上運行時調用時崩潰

[英]Crash when calling run on boost::asio::io_service

我正在嘗試編寫一個相對簡單的類'CallbackTimer',該類需要花費一些時間和一個函數,並且在經過一定時間后將調用該函數。 如有必要,可以重復幾次。

一切都按預期工作,但是在計時器結束之前幾次調用start時,我偶爾會崩潰,但是我看不出問題出在哪里。 我認為這是因為我沒有正確混合線程和io_service,但不確定。 任何幫助或指針,將不勝感激。

該類如下

CallbackTimer::CallbackTimer(const std::function<void()>& callback) :
  callback_(callback),
  currentRepeats_(0),
  //io_(boost::asio::io_service()),
  timer_(new boost::asio::deadline_timer(io_)),
  strand_(io_),
  thread_(nullptr)
{
}

CallbackTimer::~CallbackTimer()
{
  cancel();
}

void CallbackTimer::start(size_t intervalMillis, int repeats)
{
  if (thread_)
  {
    cancel();
  }

  requestedRepeats_ = repeats;
  intervalMillis_ = intervalMillis;
  currentRepeats_ = 0;
  runTimer();

  thread_.reset(new std::thread([this]()
  {
    this->io_.run();
  }));

  thread_->detach();
}

void CallbackTimer::cancel()
{
  timer_->cancel();

  if (thread_ && thread_->joinable())
  {
    thread_->join();
  }

  io_.reset();
}

void CallbackTimer::runCallback(const boost::system::error_code& e)
{
  if (e == boost::asio::error::operation_aborted)
  {
    io_.stop();
    return;
  }

  currentRepeats_++;
  callback_();

  if (currentRepeats_ >= requestedRepeats_)
  {
    io_.stop();
    return;
  }

  runTimer();
}

void CallbackTimer::runTimer()
{
  timer_->expires_from_now(boost::posix_time::millisec(intervalMillis_));
  timer_->async_wait(strand_.wrap(std::bind(&CallbackTimer::runCallback, this, std::placeholders::_1)));
}

乍看之下,存在兩個潛在問題:

  • 當對run()run_one()poll()poll_one()調用未完成時, CallbackTimer類無法保證不調用io_service::reset()的先決條件,從而導致未指定的行為。
  • CallbackTimer::runCallback()的壽命后,可調用CallbackTimer實例已結束,調用未定義的行為。

這兩個問題都源於與運行io_service的線程不同步。 CallbackTimer::start()創建線程后,將分離該線程,並且CallbackTimer::cancel()的if語句將始終為false,從而不會發生同步。 這允許以下情況:

  • thread_io_service::run()將調用io_service::reset() io_service::run()
  • thread_io_service::run()內時,擁有io_serviceCallbackTimer被釋放。

若要解決此問題,請考慮不再與thread_分離,以便可能發生同步。

為了進行進一步的調試,堆棧跟蹤或mcve可能有助於識別崩潰的確切來源。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM