CP.42: Don't wait without a condition
CP.42:不要无条件等待
Reason(原因)
A wait without a condition can miss a wakeup or wake up simply to find that there is no work to do.
无条件等待可能错过唤醒,也可能唤醒之后发现无事可做。
Example, bad(反面示例)
代码语言:javascript复制std::condition_variable cv;
std::mutex mx;
void thread1()
{
while (true) {
// do some work ...
std::unique_lock<std::mutex> lock(mx);
cv.notify_one(); // wake other thread
}
}
void thread2()
{
while (true) {
std::unique_lock<std::mutex> lock(mx);
cv.wait(lock); // might block forever
// do work ...
}
}
Here, if some other thread consumes thread1's notification, thread2 can wait forever.
这里,如果某个另外的线程消耗了线程1的通知,线程2会永远等待。
Example(示例)
代码语言:javascript复制template<typename T>
class Sync_queue {
public:
void put(const T& val);
void put(T&& val);
void get(T& val);
private:
mutex mtx;
condition_variable cond; // this controls access
list<T> q;
};
template<typename T>
void Sync_queue<T>::put(const T& val)
{
lock_guard<mutex> lck(mtx);
q.push_back(val);
cond.notify_one();
}
template<typename T>
void Sync_queue<T>::get(T& val)
{
unique_lock<mutex> lck(mtx);
cond.wait(lck, [this] { return !q.empty(); }); // prevent spurious wakeup
val = q.front();
q.pop_front();
}
Now if the queue is empty when a thread executing get() wakes up (e.g., because another thread has gotten to get() before it), it will immediately go back to sleep, waiting.
现在,当某个线程执行get唤醒时,如果队列为空(例如,由用户另外的线程已经事先执行了get),它会立刻回到休眠状态继续等待。
Enforcement(实施建议)
Flag all waits without conditions.
标记所有无条件等待。
原文链接
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#cp42-dont-wait-without-a-condition
新书介绍
以下是本人3月份出版的新书,拜托多多关注!
本书利用Python 的标准GUI 工具包tkinter,通过可执行的示例对23 个设计模式逐个进行说明。这样一方面可以使读者了解真实的软件开发工作中每个设计模式的运用场景和想要解决的问题;另一方面通过对这些问题的解决过程进行说明,让读者明白在编写代码时如何判断使用设计模式的利弊,并合理运用设计模式。
对设计模式感兴趣而且希望随学随用的读者通过本书可以快速跨越从理解到运用的门槛;希望学习Python GUI 编程的读者可以将本书中的示例作为设计和开发的参考;使用Python 语言进行图像分析、数据处理工作的读者可以直接以本书中的示例为基础,迅速构建自己的系统架构。