有了互斥量为什么还要条件变量?

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

其实答案很简单,条件变量可以在线程没必要执行的时候阻塞住,降低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的占用率。