【条件变量】 顺序操作

简介: 【条件变量】 顺序操作

条件变量 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;
}
相关文章
|
6月前
|
安全 C++
C++一分钟之-互斥锁与条件变量
【6月更文挑战第26天】在C++并发编程中,`std::mutex`提供互斥访问,防止数据竞争,而`std::condition_variable`用于线程间的同步协调。通过`lock_guard`和`unique_lock`防止忘记解锁,避免死锁。条件变量需配合锁使用,确保在正确条件下唤醒线程,注意虚假唤醒和无条件通知。生产者-消费者模型展示了它们的应用。正确使用这些工具能解决同步问题,提升并发性能和可靠性。
69 4
|
7月前
|
安全 C++
线程同步:互斥与条件变量
线程同步:互斥与条件变量
|
7月前
|
前端开发 安全 C++
C++11 条件变量
C++11 条件变量
59 0
|
7月前
|
调度
互斥锁的初步实现
互斥锁的初步实现
121 0
|
7月前
|
Linux
Linux多线程中互斥锁、读写锁、自旋锁、条件变量、信号量详解
Linux多线程中互斥锁、读写锁、自旋锁、条件变量、信号量详解
207 0
Linux多线程中互斥锁、读写锁、自旋锁、条件变量、信号量详解
|
7月前
|
前端开发 安全 C++
c++11线程、互斥量、条件变量等
c++11线程、互斥量、条件变量等
|
安全 算法 C++
C++中互斥锁的使用
我们现在有一个需求,我们需要对 g_exceptions 这个 vector 的访问进行同步处理,确保同一时刻只有一个线程能向它插入新的元素。为此我使用了一个 mutex 和一个锁(lock)。mutex 是同步操作的主体,在 C++ 11 的 <mutex> 头文件中,有四种风格的实现: mutex:提供了核心的 lock() unlock() 方法,以及当 mutex 不可用时就会返回的非阻塞方法 try_lock() recursive_mutex:允许同一线程内对同一 mutex 的多重持有 timed_mutex: 与 mutex 类似,但多了 try_lock_for() t
109 0
|
安全 算法 C++
C++11中的互斥锁讲解
C++11中的互斥锁讲解
113 0
条件变量的使用
条件变量的使用
81 0
条件变量的使用
|
安全 API
互斥锁的使用
互斥锁的使用
95 0
互斥锁的使用