2

我写了一个定时器,它的工作方式如下:一个使用定时器的类实现了一个回调函数call_()。计时器在单独的线程中运行,并call_()在计时器到期时执行。

我的测试程序如下:

void TestCase::loop()
{
  unique_lock<mutex> lock(*this);

  while(running_)
  {
     timer_->SetTimer(time);
     signal_.wait(lock);
     do_something();
  }
}

void TestCase::call_()
{
  signal_.notify_all();
}

如果time非常小(例如 2 毫秒),则测试程序有时会执行do_something(),有时则不会(在测试程序的不同运行中)。

我的猜测是竞争条件,似乎 if timeis smallcall()_是在之前执行(因此signal_.notify_all()signal_.wait(lock)

如果我this_thread::sleep(posix_time::milliseconds(2))之前添加signal_.notify_all()do_something()几乎每次运行都会执行,并且sleep(5)一切正常。

我如何保证signal_.wait(lock)之前执行signal_.notify_all()

4

1 回答 1

1

使用非常小的超时值,无法保证主线程signal_wait在计时器线程执行语句之前到达signal_.notify_all语句。

当您使用一次性计时器时,更好的选择是使用信号量而不是条件变量来同步两个线程。

正如您在条件变量中看到的那样,为了使机制正常工作,必须执行等待和通知的顺序。

使用信号量,执行等待的线程也将停止,直到另一个线程发布信号量,但没有要求以什么顺序到达等待和发布操作。如果首先到达该帖子,则等待立即返回(并且成功)。

于 2012-11-29T13:52:24.870 回答