std::condition_variable 条件变量类型

一、成员函数 wait()、 notify_one() 和 notify_all()

notify_one():任意唤醒一个线程中condition_variable的wait
notify_all():唤醒所有线程中condition_variable的wait

// 使用例子
class MyClass{  // 模拟给一个消息队列发消息和处理消息
public:
    void WriteMessage() // 模拟发消息,也就是往消息队列中写
    {
        for (int i = 0; i < 10000; ++i)
        {
            cout << "插入一个元素:" << i << endl;
            std::unique_lock<std::mutex> myLock(m_mutex);
            m_messages.push_back(i);
            m_condition.notify_one();   // 尝试把wait的线程唤醒
        }
    }

    void ReadMessage()   // 模拟处理消息队列中的消息,从中读,也删除
    {
        int command = 0;
        while (true)
        {
            std::unique_lock<std::mutex> myLock(m_mutex);

            // wait() 第二个参数 类型是一个可调用对象
            // 第二个参数返回true,wait()直接返回,程序继续往下执行
            // 第二个参数返回false,wait()将解锁互斥量,并堵塞到本行
            // (意思是返回false时,本线程的代码停在这一行,之前上锁的互斥量也被解锁,
            // 这样不影响其他线程拿到这个互斥量的锁)
            //   直到其他某个线程调用notify_one()成员函数为止、
            // 第二个参数的默认值是false
            // 当其他线程用notify_one()把本wait() 的状态唤醒(原来是阻塞状态)
            // 然后,wait()会不断尝试去拿到这个锁,如果获取不到,程序仍会卡在这里
            // 如果获取到,wait()就继续执行,(第二个参数返回false继续睡眠,
            // 第二个参数返回true,继续往下执行,同时上锁了互斥量)
            // 如果没有第二个参数,则wait()被唤醒之后,直接往下走,
            // 相当于wait()被唤醒之后,第二个参数默认值变成true。
            m_condition.wait(myLock, [this] {  // 第二个参数是一个匿名函数,lambda表达式
                if (!m_messages.empty())
                {
                    return true;
                }
                return false;
            });
            // 能执行到这,说明m_messages 中已经有数据了
            command = m_messages.front();
            m_messages.pop_front();
            myLock.unlock();   // unique_lock 可以自己手动解锁
            cout << "取出一个元素" << command << endl;
        }
    }

private:
    list<int> m_messages;   // 模拟消息队列
    mutex m_mutex;   // 创建一个互斥量成员对象
    std::condition_variable   m_condition;   // 定义一个条件变量对象
};

int main()
{
    MyClass ele;
    std::thread writeThread(&MyClass::WriteMessage, &ele);  // 
    std::thread readThread(&MyClass::ReadMessage, &ele);    // 
    readThread.join();
    writeThread.join();

    cout << "主线程" << endl;
    system("pause");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/zhiminzeng/p/13194776.html