C++ 防止种族状况

C++ 防止种族状况,c++,multithreading,boost,C++,Multithreading,Boost,我编写了一个计时器,其工作方式如下: 使用计时器的类实现了一个回调函数call()。 计时器在单独的线程中运行,并在计时器过期时执行调用() 我的测试程序如下: void TestCase::loop() { unique_lock<mutex> lock(*this); while(running_) { timer_->SetTimer(time); signal_.wait(lock); do_something(); }

我编写了一个计时器,其工作方式如下: 使用计时器的类实现了一个回调函数
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();
}
void TestCase::loop()
{
唯一的锁(*此);
当(运行时)
{
定时器->设置定时器(时间);
信号等待(锁定);
做某事;
}
}
void TestCase::调用
{
发出信号通知所有人();
}
如果
时间
非常小(例如2ms),测试程序有时执行
do_something()
,有时不执行(在测试程序的不同运行中)

我的猜测是一种竞争条件,似乎如果
时间
很小,则在
发出信号等待(锁定)
之前执行
调用()

如果我在
signal.notify\u all()之前添加
这个线程::sleep(posix\u time::毫秒(2))
do\u something()
几乎在每次运行中都会执行,对于
sleep(5)
来说,一切正常


如何确保在执行
signal.notify.all()
之前执行
signal.wait(lock)

对于非常小的超时值,无法保证主线程在计时器线程执行
signal.notify.all
语句之前达到
signal.wait
语句

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

正如您在条件变量中看到的那样,为了使机制正常工作,必须按照一定的顺序执行wait和notify


对于一个信号量,执行等待的线程也将停止,直到另一个线程发布该信号量,但不要求达到等待和发布操作的顺序。如果先到达post,等待将立即返回(并且成功)。

超时值非常小,无法保证主线程在计时器线程执行
signal\u wait
语句之前到达
signal\u。notify\u all
语句

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

正如您在条件变量中看到的那样,为了使机制正常工作,必须按照一定的顺序执行wait和notify


对于一个信号量,执行等待的线程也将停止,直到另一个线程发布该信号量,但不要求达到等待和发布操作的顺序。如果先到达post,等待将立即返回(并且成功)。

您在哪里更改running的值?我的猜测是,你的问题更多地与这个变量有关。如果你必须确保“等待”在“通知”之前执行,那么这是错误的信号类型。这里需要一个线程安全条件变量。在运行的测试程序中,构造函数中的_uu设置为true,在testcase的析构函数中设置为false。请提供一个有效的ehm,编撰example@ActiveTrayPrntrTagDataStrDrvr:这是我的第一个想法:-)我使用了
boost::conditional_variable signal.
boost是否有线程安全的条件变量?我在文档中找不到任何内容。您在哪里更改运行的值?我的猜测是,你的问题更多地与这个变量有关。如果你必须确保“等待”在“通知”之前执行,那么这是错误的信号类型。这里需要一个线程安全条件变量。在运行的测试程序中,构造函数中的_uu设置为true,在testcase的析构函数中设置为false。请提供一个有效的ehm,编撰example@ActiveTrayPrntrTagDataStrDrvr:这是我的第一个想法:-)我使用了
boost::conditional_variable signal.
boost是否有线程安全的条件变量?我没有在医生里找到什么。谢谢,这解决了我的问题。我自己尝试实现一个信号量类,因为我不确定boost是否提供了一个更简单的解决方案(因为boost中没有信号量),boost.Interprocess库中是否有信号量。您可以使用
屏障
而不是信号灯(它只是让两个线程互相等待,而不是只让线程a等待线程B通过某个点),谢谢,这解决了我的问题。我自己尝试实现一个信号量类,因为我不确定boost是否提供了一个更简单的解决方案(因为boost中没有信号量),boost.Interprocess库中是否有信号量。您可以使用
屏障
而不是信号量(它只是让两个线程互相等待,而不是只让线程a等待线程B通过某个点)