条件变量 std::condition_variable 是为了解决死锁而生,当互斥操作不够用而引入的。比如,线程可能需要等待某个条件为真才能继续执行,而一个忙等待循环中可能会导致所有其他线程都无法进入临界区使得条件为真时,就会发生死锁。所以,condition_variable 实例被创建出现主要就是用于唤醒等待线程从而避免死锁。std::condition_variable 的 notify_one() 用于唤醒一个线程;notify_all()则是通知所有线程。
值得一提的是,在生产者中我们虽然可以使用 notify_one(),但实际上并不建议在此处使用,因为在多消费者的情况下,我们的消费者实现中简单放弃了锁的持有,这使得可能让其他消费者争夺此锁,从而更好的利用多个消费者之间的并发。话虽如此,但实际上因为 std::mutex 的排他性,我们根本无法期待多个消费者能真正意义上的并行消费队列的中生产的内容,我们仍需要粒度更细的手段。
#include <atomic> #include <iostream> #include <thread> #include <condition_variable> #include <mutex> std::atomic<int> count = {0}; // g++ atomic.cpp -lpthread -std=c++14 -latomic struct A { float x; int y; long long z; }; std::condition_variable cv; std::mutex _mutex; bool notified = false; int main() { #if 0 std::thread t1([]{ while(1){ if(count == 0){ std::cout<< "t1:1"<<'\n'; count.fetch_add(1); } } }); std::thread t2([]{ while(1){ if(count == 1){ std::cout<< "t2:2"<<'\n'; count.fetch_sub(1); } } }); t1.join(); t2.join(); #elif 0 std::atomic<A> a; std::cout << std::boolalpha << ":" << a.is_lock_free() << std::endl; #elif 1 std::thread write_th([]{ while(1){ std::unique_lock<std::mutex> lock(_mutex); while(notified){ cv.wait(lock); } std::cout << "write_th write"<<'\n'; notified = true; cv.notify_all(); } }); std::thread read_th([]{ while(1){ std::unique_lock<std::mutex> lock(_mutex); while(!notified){ cv.wait(lock); } std::cout << "read_th read"<<'\n'; notified = false; cv.notify_all(); } }); write_th.join(); read_th.join(); #endif return 0; }