互斥量已经可以保证线程的同步,那为什么还要弄条件变量?
其实答案很简单,条件变量可以在线程没必要执行的时候阻塞住,降低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的占用率。