条件变量用于检测C ++中的事件scott meyers

时间:2015-12-03 11:49:07

标签: c++ c++11 effective-c++

我正在阅读Scott Meyers的书中有效现代C ++中的条件变量,下面是文本。

std::condition_variable   cv
std::mutex                m

T1 (detecting task)

...
cv.notify_one();


T2 (reacting task)

...
{
  std::unique_lock<std::mutex> lk(m);
  cv.wait(lk);

  ...
}

这里的作者提到如下

  

互斥锁用于控制对共享数据的访问,但它完全是   检测和反应任务可能不需要这样做   调解。例如,检测任务可能负责   初始化全局数据结构,然后将其转换为反应   任务使用。如果检测任务从不访问数据结构   在初始化之后,如果反应任务之前从未访问它   检测任务表明它已准备就绪,两个任务将保持不变   通过程序逻辑走出彼此的方式。没有必要   对于互斥体。

在上面的文字中,我很难理解

  1. 作者的意思是“两个任务将通过程序逻辑保持彼此”?

  2. 作者的意思是什么,不需要互斥?

4 个答案:

答案 0 :(得分:2)

互斥用于解决竞争条件,例如:

  

当两个或多个线程可以访问共享数据并且他们尝试同时更改它时,会出现争用情况

在你的情况下不会发生,因为在你的结构上进行的操作将在不同的时间范围内完成,即:不会引起任何竞争条件。由于您不需要同时编写两个线程,因此您不需要互斥锁。

同时考虑到当你有&#34; check-then-act&#34; (例如&#34;检查&#34;如果值是X,那么&#34;行动&#34;做依赖于值为X的事情)并且另一个线程对&#34之间的值做某事;检查&#34;和&#34;行为&#34;。

答案 1 :(得分:2)

检测任务和响应任务都访问相同的数据,但程序逻辑保证它们不会同时访问该数据。因此,它们不需要互斥(或任何其他机制)来防止对数据的并发访问,因为通过其他方式阻止了这种并发访问。另一种方法是程序逻辑。

&#34;程序逻辑&#34;指程序的控制流程。我将稍微重新格式化代码:

Data shared_data;

std::condition_variable cv;
std::mutex m;

void detecting_task()
{
  initialise(shared_data);
  cv.notify_one();
}

void reacting_task()
{
  {
    std::unique_lock<std::mutex> lk(m);
    cv.wait(lk);
  }
  process(shared_data);
}

即使detecting_taskreacting_task同时开始,您也可以看到他们无法同时对shared_data采取行动。程序逻辑是detecting_task仅在通知 cv之前触及数据,而reacting_task仅触及 {之后的数据 {1}}会收到通知。因此它们不可能重叠,因此不需要通过互斥锁来保护cv

答案 2 :(得分:1)

基本上,文本说:当两个线程不访问任何共享资源时,不需要同步对资源的访问。也就是说,如果每个线程只使用自己的数据结构而没有其他线程访问它们,则不需要通过互斥锁进行任何锁定 - 没有其他线程可以访问相应的资源。

鉴于上下文,它似乎是一个简单的消息传递系统,即使用互斥锁和条件变量的东西,它描述了所有必要的同步:“检测线程”注意到某些内容并通过消息发送通知将系统传递给“反应线程”。它们之间唯一共享的是消息传递对象。

答案 3 :(得分:0)

我也不完全理解引文。如果您不保护共享数据,则无需使用互斥锁进行内存访问。这可能意味着,检测任务不需要锁定互斥锁。

但是,condition_variable需要一个互斥量才能工作。这是因为,至少一些底层操作系统实现需要一个互斥锁,例如pthreads

请参阅:Why do pthreads’ condition variable functions require a mutex?