在C++scott-meyers中检测事件时使用的条件变量
condition variable usage in detecting an event in C++ scott meyers
我正在阅读Scott Meyers的Effective Modern 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);
...
}
以下是作者提到的
Mutex用于控制对共享数据的访问,但它完全检测和反应任务可能不需要调解。例如,检测任务可能负责初始化全局数据结构,然后将其转换为反应任务以供使用。如果检测任务从未访问过数据结构在初始化它之后,如果反应任务以前从未访问过它检测任务表明它已准备好,两个任务将保留通过程序逻辑互相让开。没有必要用于互斥。
在上面的文本中,我很难理解
作者所说的"通过程序逻辑,两个任务将互不妨碍"是什么意思?
作者所说的不需要互斥是什么意思?
Mutex用于解决竞争条件,例如:
当两个或多个线程可以访问共享数据,并且它们试图同时更改时,就会出现竞争情况
在你的情况下,这不会发生,因为对你的结构所做的操作将在不同的时间框架内完成,即:不会造成任何比赛条件。由于不需要两个线程同时写入,因此不需要互斥。
还要考虑的是,当你有"检查然后行动"(例如,如果值是X,则"检查",然后"行动"来做取决于值是X的事情),而另一个线程对"检查"answers"行动"之间的值做了一些事情时,大多数问题都会出现。
检测任务和反应任务都访问相同的数据,但程序逻辑保证它们永远不会同时访问该数据。因此,它们不需要互斥(或任何其他机制)来阻止对数据的并发访问,因为这种并发访问是通过其他方式阻止的。另一种方法是程序逻辑。
"程序逻辑"是指程序的控制流程。我将稍微重新格式化代码:
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_task
和reacting_task
同时启动,您也可以看到它们不可能同时作用于shared_data
。程序逻辑使得detecting_task
仅在cv
被通知之前接触数据,并且reacting_task
仅在cv
被通知之后接触数据。因此,它们不可能重叠,因此不需要通过互斥来保护shared_data
。
从本质上讲,文本说:当两个线程不访问任何共享资源时,就不需要同步访问资源。也就是说,如果每个线程只使用自己的数据结构,而没有其他线程访问它们,那么就不需要通过互斥锁进行任何锁定——没有其他线程会访问相应的资源。
在给定上下文的情况下,似乎描述了一个简单的消息传递系统,即使用互斥和条件变量的东西,它完成了所有必要的同步:"检测线程"注意到一些东西,并通过消息传递系统向"反应线程"发送通知。它们之间唯一共享的是消息传递对象。
我也不完全理解引文。如果您不保护共享数据,那么互斥锁对于内存访问是不必要的。这可能意味着,检测任务将不需要锁定互斥锁。
但是,c++11 condition_variable
需要一个互斥锁才能工作。这是因为,至少一些底层操作系统实现需要互斥,比如pthreads
请参阅:为什么pthreads的条件变量函数需要互斥?
- 基于模板值的条件变量
- 没有超时的C++条件变量
- 在条件变量中触发错误信号的频率是多少
- 在通知提升间处理条件变量时未按住锁会导致问题
- 通知条件变量后使用互斥锁
- 滥用条件变量
- 升压插值条件变量可以虚假唤醒吗?
- 子线程中的条件变量等待停止主线程中的执行
- 条件变量基本示例
- 正在连接的等待条件变量的线程会发生什么情况?
- C++11如何在1个线程中使用条件变量处理2个线程安全队列
- 当线程处理不同的类时,应该在哪里声明条件变量、互斥对象
- 为什么在同一条件变量上使用多个互斥锁会使此代码崩溃?
- 条件变量:wait_for.gcc错误
- 如何"stop"正在等待条件变量的分离线程?
- 如何杀死被条件变量锁定的线程?
- 使用互斥锁和条件变量作为成员时如何修复"use of deleted function"?
- C++ 多个使用者线程卡在条件变量上
- POSIX 条件变量和互斥体"竞争"
- 将cpp_redis pub/sub与条件变量一起使用时出现问题