• C++条件变量


    1.作用:在C++11中,我们可以使用条件变量(std::condition_variable)实现多个线程间的同步操作;当条件不满足时,相关线程被一直阻塞,并释放CPU,直到某种条件出现,这些线程才会被唤醒。条件变量需要和互斥量(锁)一起搭配使用。

    用在多线程中。

    线程A:等待一个条件满足

    线程B:专门在消息队列中扔消息,线程B触发了这个条件,A就满足条件了,可以继续执行

    2.常用的成员函数:

      (1)wait():阻塞当前线程,直到条件变量被唤醒。

      (2)wait_for:阻塞当前线程,直到条件变量被唤醒或到达指定时长后。

      (3)wait_until:阻塞当前线程,直到条件变量被唤醒,或知道抵达指定的时间点。

      (4)notify_once:通知一个等待的线程。

      (5)notify_all:通知所有等待的线程。

    3.范例代码

    #include <iostream>
    #include<thread>
    #include<string>
    #include<vector>
    #include<algorithm>
    #include<windows.h>
    #include<list>
    #include<mutex>
    
    using namespace std;
    
    class myClass
    {
    public:
        void AddOrder()
        {
            for (int i = 0; i < 10000; i++)
            {
                cout << "addOrder执行,插入一个元素" << i << endl;
                std::unique_lock<std::mutex> sbGuard(m_mutex);
                m_orderList.push_back(i);
    
                //我们尝试把wait()的线程唤醒,
                //注意:如果其他线程在wait时,调用notify_one,可以唤醒,但是当其他线程没有在wait时,执行的notify_one没有用
                m_Cond.notify_one();    
    
            }
        }
    
        void RemoveOrder()
        {
            int command;
            while (true)
            {
                std::unique_lock<std::mutex> sbGuard(m_mutex);
                //如果第二个参数lambda表达式返回值是true,那么wait()直接返回;
                //如果第二个阐述lambda表达式返回值是false,那么wait()将解锁互斥量,并阻塞到本行,
                //那么阻塞到什么时候为止呢,阻塞到其他某个线程调用notify_once()成员函数为止;
                //如果wait()没有第二个参数:m_Cond.wait(sbGuard),那么就跟第二个参数lambda表达式返回false效果一样,
                //当其他线程用notify_once()将本wait(原来是阻塞状态)唤醒,wait就开始回复工作,wait不断的尝试重新获取互斥量锁
                //    (a)如果拿不到锁,它会不断尝试取获取
                //    (b)如果获取到锁后:
                //        (b.1):拿到锁,如果wait有第二个参数,就判断这个lambda表达式,如果lambda表达式为false,那么wait又对互斥量锁解锁又开始阻塞
                //        (b.2):如果lambda表达式为true,则wait返回,流程往下走
                //       (b.3):如果wait没有第二个参数,则wait返回,流程往下走
                m_Cond.wait(sbGuard, [this] {             //一个lambda就是一个可调用对象(函数)
                    if (!m_orderList.empty())
                        return true;
                    return false;
                });
    
                command = m_orderList.front();    // 返回m_orderList第一个元素
                m_orderList.pop_front();        //移除m_orderList第一个元素
                sbGuard.unlock();           //unique_lock灵活,可以随时解锁,以免锁住太长时间
    
                cout << "RemoveOrder取出一个元素" << command << endl;
    
                //其他任务
            }
        }
    
    private:
        std::list<int> m_orderList;
        std::mutex m_mutex;
        std::condition_variable m_Cond;    //生成一个条件变量对象
    };
    
    int main()
    {
        myClass my;
    
        std::thread obj1(&myClass::AddOrder, &my);
        std::thread obj2(&myClass::RemoveOrder, &my);
        obj1.join();
        obj2.join();
    
        system("pause");
    }
    View Code
    111
  • 相关阅读:
    Oracle11g聚合函数
    和为S的连续正数数列,动态规划,C++
    统计一个数组在排序数组中出现的次数,C++,二分查找
    寻找两个链表的第一个公共子节点,C++
    二维数组中的查找
    数组中的逆序对,C++,分治算法
    得到从小到大的第N个丑数的三种方式(C++)一维动态规划
    连续字数组的最大和(Java)一个int数组,求其中的最大的连续数的和
    n个整数,求这中间最小的k个整数(Java)
    两个字符串的最长公共子串求法(C++、动态规划)
  • 原文地址:https://www.cnblogs.com/zwj-199306231519/p/13550427.html
Copyright © 2020-2023  润新知