condition_variable中的和wait_once和notify_one及notify_all实例代码

// ConsoleApplication6.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include<thread>
#include<iostream>
#include<list>
#include<mutex>
using namespace std;
mutex mut_one; 
once_flag gl_flag;//标记

class A
{
private:
    list<int> msgRecvQueue;
    mutex my_mutex;
    
my_cond;
//生成一个条件对象 static A* Instance; public: static A* GetInstance() { if (Instance == NULL) { unique_lock<mutex> my(mut_one); if (Instance == NULL) { Instance = new A; static A_Guard gl; } } return Instance; } class A_Guard { public: ~A_Guard() { if (A::Instance != NULL) { delete A::Instance; A::Instance = NULL; } } }; void enmsg() { for (int i = 1; i <= 100; i++) { msgRecvQueue.push_back(i); cout << "压入数据成功,数据为:" << i << endl; my_cond.notify_one();//作用是为了唤醒堵塞的wait } } void outmsg() { int command = 0; while (true) { unique_lock<mutex> sbg(my_mutex); my_cond.wait(sbg, [this] { if (!msgRecvQueue.empty()) return true; else return false; });//第二个参数如果返回false,wait会解锁,并堵塞在这一行等待notify_one //上面假设notify_one执行了唤醒的操作,那么第二个参数里面的list就不为空了,会返回true, //返回true之后也就意味着不堵塞了,继续执行以下的代码 command = msgRecvQueue.front(); cout << "弹出来的数据是" << command << endl; msgRecvQueue.pop_front(); } } }; A* A::Instance = NULL; void Thread_one() { A *s = A::GetInstance(); s->enmsg(); } void Thread_two() { A*s = A::GetInstance(); s->outmsg(); } int main() { thread thone(Thread_one); thread thtwo(Thread_two); thone.join(); thtwo.join(); return 0; }

把notify_one变为notify_all的代码:

// ConsoleApplication6.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include<thread>
#include<iostream>
#include<list>
#include<mutex>
using namespace std;
mutex mut_one; 
once_flag gl_flag;//标记

class A
{
private:
    list<int> msgRecvQueue;
    mutex my_mutex;
    condition_variable  my_cond;//生成一个条件对象
    static A* Instance;
public:
    static A* GetInstance()
    {
        if (Instance == NULL)
        {
            unique_lock<mutex> my(mut_one);
            if (Instance == NULL)
            {
                Instance = new A;
                static A_Guard gl;
            }
        }
        return Instance;
    }

    class A_Guard
    {
    public:
        ~A_Guard()
        {
            if (A::Instance != NULL)
            {
                delete A::Instance;
                A::Instance = NULL;
            }
        }
    };
    void enmsg()
    {
        for (int i = 1; i <= 100; i++)
        {
            msgRecvQueue.push_back(i);
            cout << "压入数据成功,数据为:" << i << endl;
            //my_cond.notify_one();//作用是为了唤醒堵塞的wait
            my_cond.notify_all();//故名思意,唤醒的不知一个wait
        }
    }

    void outmsg()
    {
        int command = 0;
        while (true)
        {
            unique_lock<mutex> sbg(my_mutex);
            my_cond.wait(sbg, [this] {
                if (!msgRecvQueue.empty())
                    return true;
                else
                    return false;
            });//第二个参数如果返回false,wait会解锁,并堵塞在这一行等待notify_one
            //上面假设notify_one执行了唤醒的操作,那么第二个参数里面的list就不为空了,会返回true,
            //返回true之后也就意味着不堵塞了,继续执行以下的代码
            command = msgRecvQueue.front();
            cout << "弹出来的数据是" << command << endl;
            msgRecvQueue.pop_front();
        }
    }

};


A* A::Instance = NULL;
void Thread_one()
{
    A *s = A::GetInstance();
    s->enmsg();
}
void Thread_two()
{
    A*s = A::GetInstance();
    s->outmsg();
}
void Thread_three()
{
    A*s = A::GetInstance();
    s->outmsg();
}
int main()
{
    
    thread thone(Thread_one);
    thread thtwo(Thread_two);
    thread three(Thread_three);
    thone.join();
    thtwo.join();
    three.join();
    return 0;
}

把其中的一部分拿出来分析一下,比如这段代码:

while (true)
        {
            unique_lock<mutex> sbg(my_mutex);
            my_cond.wait(sbg, [this] {
                if (!msgRecvQueue.empty())
                    return true;
                else
                    return false;
            });//第二个参数如果返回false,wait会解锁,并堵塞在这一行等待notify_one
            //上面假设notify_one执行了唤醒的操作,那么第二个参数里面的list就不为空了,会返回true,
            //返回true之后也就意味着不堵塞了,继续执行以下的代码
            command = msgRecvQueue.front();
            cout << "弹出来的数据是" << command << endl;
            msgRecvQueue.pop_front();
        }

变为:

    while (true)
        {
            unique_lock<mutex> sbg(my_mutex);
            my_cond.wait(sbg, [this] {
                if (!msgRecvQueue.empty())
                    return true;
                else
                    return false;
            });//第二个参数如果返回false,wait会解锁,并堵塞在这一行等待notify_one
            //上面假设notify_one执行了唤醒的操作,那么第二个参数里面的list就不为空了,会返回true,
            //返回true之后也就意味着不堵塞了,继续执行以下的代码

            sbg.unlock();//把锁打开了
            chrono::milliseconds dura(2000);
            this_thread::sleep_for(dura);
            command = msgRecvQueue.front();
            cout << "弹出来的数据是" << command << endl;
              msgRecvQueue.pop_front();
        }

未完

原文地址:https://www.cnblogs.com/SunShine-gzw/p/13521163.html