zoukankan      html  css  js  c++  java
  • 有了互斥量为什么还要条件变量?

    互斥量已经可以保证线程的同步,那为什么还要弄条件变量?

    其实答案很简单,条件变量可以在线程没必要执行的时候阻塞住,降低CPU的占用率。

    用代码来测试下

    互斥量

    #include <mutex>
    #include <iostream>
    #include <queue>
    #include <thread>
    
    using namespace std;
    
    queue<int> msgs;
    mutex m;
    condition_variable cond;
    long long loops = 0;
    
    void writerfunc()
    {
        for (int i = 0; i < 5; i++)
        {
            this_thread::sleep_for(chrono::seconds(1));
            lock_guard<mutex> lck(m);
            cout << "Write Message: " << i << endl;
            msgs.push(i);
        }
    }
    
    
    void readerfunc()
    {
        while (true)
        {
            loops++;
            lock_guard<mutex> lck(m);
            if (!msgs.empty())
            {
                int s = msgs.front();
                cout << "Read Message: " << s << endl;
                msgs.pop();
                if (s == 4)
                    break;
            }
        }
    }
    
    
    int main()
    {
        thread reader(readerfunc);
        thread writer(writerfunc);
        writer.join();
        reader.join();
        cout << "轮询次数:" << loops << endl;
        return 0;
    }
    

     输出结果:

     可以看出来,使用互斥量后线程轮训次数非常非常非常多

    条件变量

    #include <mutex>
    #include <iostream>
    #include <queue>
    #include <thread>
    
    using namespace std;
    
    queue<int> msgs;
    mutex m;
    condition_variable cond;
    long long loops = 0;
    
    void writerfunc()
    {
        for (int i = 0; i < 5; i++)
        {
            this_thread::sleep_for(chrono::seconds(1));
            unique_lock<mutex> lck(m);
            cout << "Write Message: " << i << endl;
            msgs.push(i);
            cond.notify_one();
        }
    }
    
    void readerfunc()
    {
        while (true)
        {
            loops++;
            unique_lock<mutex> lck(m);
            cond.wait(lck);
            if (!msgs.empty())
            {
                int s = msgs.front();
                cout << "Read Message: " << s << endl;
                msgs.pop();
                if (s == 4)
                    break;
            }
        }
    }
    
    int main()
    {
        thread reader(readerfunc);
        thread writer(writerfunc);
        writer.join();
        reader.join();
        cout << "轮询次数:" << loops << endl;
        return 0;
    }

    输出结果:

     可以看出,使用条件变量轮询次数显著下降,可以有效降低CPU的占用率。

  • 相关阅读:
    SpringBoot集成Redis
    独享锁 & 共享锁
    公平锁与非公平锁
    如何上传本地代码到码云
    SpringBoot+Mybatis+Pagehelper分页
    SpringBoot集成Mybatis(0配置注解版)
    高并发下接口幂等性解决方案
    SpringBoot全局配置文件
    干货
    Spring读取外部的资源配置文件—@PropertySource和@Value实现资源文件配置
  • 原文地址:https://www.cnblogs.com/fensi/p/13123974.html
Copyright © 2011-2022 走看看