CppCoreGuidelines CP.42 在 wait 中设置判断条件
05 July 2023
“Don’t wait without a condition”
理由
在 wait 中不设置判断条件的话,会发现线程醒来之后并没有任务要处理。
坏例子
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 ... } }
这里,如果某个其他线程用掉了 thread1
的通知, thread2
会一直等待。
例子
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(); }
现在,如果消息是空的,调用 get()
的线程会醒来,发现其他线程在它之前已经调用了 geet()
,那么这个线程会马上睡眠,继续等待。
强化
标记 wait 中没设置判断条件的情况。