欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

多线程中的条件变量

时间:2023-04-22

(192条消息) 《c++新经典》C++11并发与多线程笔记(8)_中国彭于晏杭州分晏的博客-CSDN博客

问题一:如果说第一个读数据的线程中, wait第二个参数返回的是false的话,程序就会阻塞,沉睡在这里,直到另一个线程使用notify_one函数为止,notice_one函数将其唤醒后,wait就开始工作了。

恢复wait()后干什么活?
            1.wait()会和其他的线程继续竞争锁,不断尝试重新获取互斥量锁,如果获取不到,那么流程就卡在wait这里等着获取;
               如果获取到了(等于加了锁),那么wait就继续执行

        如果wait有第二个参数(lambda表达式),就判断这个lambda表达式,
        如果lambda表达式为false,那wait又对互斥量解锁,然后又休眠等待再次被唤醒
        如果lambda表达式为true,则wait返回,流程走下来(此时,互斥锁被锁着)
        如果wait没有第2个参数,则wait返回,流程走下来。

值得注意的是notify_one只有在wait()沉睡的时候才会有唤醒的功能。

问题二:为什么需要wait()?

    //把消息队列从容器中取出来的线程
    void outMesgRecvQueue()
    {
        for (int i = 0; i < 100000; ++i)
        {  std::lock(my_mutex1, my_mutex2);//std::lock(my_mutex);
            if (!list_msg.empty())
            {
                int command = list_msg.front();
                            
              
                list_msg.pop_front();
                my_mutex.unlock();
                
            }
            else
            {
                cout << "消息队列为空" << endl;
            }
        }
        cout << "outMesgRecvQueue end" << endl;
    }

其实是为了节约资源,因为,我们在取数据的时候,需要现有个判空函数,判空其实和读数据的线程就有冲突了,所以要在判空之前加上锁,但是每一次判空前都要加锁的话,就会浪费资源,为此,我们可以用双重检测的写法。

 void outMesgRecvQueue()
    {
        for (int i = 0; i < 100000; ++i)
        { if(!list_msg.empty()){

            std::lock(my_mutex1, my_mutex2);//std::lock(my_mutex);
            if (!list_msg.empty())
            {
                int command = list_msg.front();
                            
              
                list_msg.pop_front();
                my_mutex.unlock();
          }      
            }
            else
            {
                cout << "消息队列为空" << endl;
            }
        }
        cout << "outMesgRecvQueue end" << endl;
    }

但是这样的写法,思路比较难受为此我们使用了条件变量。引用了wait(锁,条件判断的lambada函数),当判断函数(其实就是判空函数,返回了true)则线程就可以继续走下去,否则就等待别的线程中的notify_one唤醒。

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。