zoukankan      html  css  js  c++  java
  • 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();
            }

    未完

  • 相关阅读:
    C# 数组 随机 排序
    安全防护之加盐慢哈希加密
    NLog的介绍使用
    xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance(xsi:schemaLocation详解)
    如何计算时间复杂度(转)
    ppp协议介绍(转)
    Netlink 介绍(译)
    TIME_WAIT状态的一些总结
    带头结点单链表的翻转(递归)
    压缩前端文件(html, css, js)
  • 原文地址:https://www.cnblogs.com/SunShine-gzw/p/13521163.html
Copyright © 2011-2022 走看看