C++11的条件变量和Lambda表达式

#include <iostream>
#include <mutex>
#include <list>
#include <map>
#include <string>
#include <thread>
#include <condition_variable>


using namespace std;

class Conditional
{
public:
    void inMsgRecvQueue()
    {
        for (int i = 0; i < 10000; i++)
        {
            cout << "插入一个元素" << i << endl;
            std::unique_lock<std::mutex> Mutex_Quique(m_Thread_Mutex);
            m_msgRecvQueue.push_back(i);
            m_condition.notify_one(); //条件变量为真 通知调用wait函数的线程进行解锁 执行代码
            //m_condition.notify_all() 通知所有等待的变为真
        }
        return;
    }

    bool outMsgRecvProc(int & command)
    {

        while (true)
        {
            std::unique_lock<std::mutex> Mutex_Quique(m_Thread_Mutex);

            // 等待上边调用notify_one函数的通知, 如果没有通知它会自动解锁的 因为上边用到了类模板自动上锁,如果不自动解锁,上边的代码执行不了
#if 0
                捕获列表    作用
                [a]    a为值传递
                [a, &b]    a为值传递,b为引用传递
                [&]    所有变量都用引用传递。当前对象(即this指针)也用引用传递。
                [=]    所有变量都用值传递。当前对象用引用传递。
#endif
            m_condition.wait(Mutex_Quique, [&] //lambda表达式是一个匿名函数
            {
                if (!m_msgRecvQueue.empty())
                    return true;
                return false;
            });

#if 0
            //for (auto it = m_msgRecvQueue.begin(); it != m_msgRecvQueue.end(); ++it)

            //C++11遍历容器的方法之一,只能是只读的
            for (auto n : m_msgRecvQueue)
            {
                //cout << n << endl;
            }
            //加上引用就可以对容器内的值进行修改
            for (auto &n : m_msgRecvQueue)
            {
                n = 999999;
                cout << n << endl;
            }
#endif

            command = m_msgRecvQueue.front();
            m_msgRecvQueue.pop_front();
            cout << "取出一个元素为" << command << endl;
            Mutex_Quique.unlock(); //这需要提前解锁,不用调用自动解锁析构函数 因为下边可以有需要长时间处理的代码

            //需要长时间处理的代码
        }
    }

    void outMsgRecvQueue()
    {
        int command = 0;
        for (int i = 0; i < 10000; i++)
        {
            bool result = outMsgRecvProc(command);
            if (result)
            {
                cout << "取出一个元素" << command << endl;
            }
            else
            {
                cout << "当前消息队列为空" << endl;
            }
        }
    }


public:
    map<int, string> m_TestDataMap;

private:
    list<int> m_msgRecvQueue;

    std::mutex m_Thread_Mutex;
    std::condition_variable m_condition; //条件变量对象

};


#if 0
// 禁止类被继承的关键字
class A final
{

};
class V : public A
{


};
#endif
int main(void)
{
    
#if 0
    条件变量
    std::condition_variable实际上是一个类, 是一个和条件相关的类, 说白了就是在等一个条件达成
    C++中,一个lambda表达式表示一个可调用的代码单元。我们可以将其理解为一个未命名的内联函数。它与普通函数不同的是,lambda必须使用尾置返回来指定返回类型。
#endif

    Conditional oTestObj;

#if 0
    
    oTestObj.m_TestDataMap[0] = "0000";
    oTestObj.m_TestDataMap[1] = "1111";
    oTestObj.m_TestDataMap[2] = "2222";
    oTestObj.m_TestDataMap[3] = "3333";

    for (auto &n : oTestObj.m_TestDataMap)
    {
        n.second = "99999";

        cout << n.second << endl;
    }

#endif

    std::thread InThread(&Conditional::inMsgRecvQueue, &oTestObj);
    std::thread OutThread(&Conditional::outMsgRecvQueue, &oTestObj); //第二个参数是引用,才能保证线程中创建的是同一个对象
    
    OutThread.join();
    InThread.join();

    return 0;
}

 

posted @ 2020-03-05 21:18  骄傲到自负  阅读(636)  评论(0)    收藏  举报