互斥量既然能解决问题,为什么要用条件变量?
新手刚刚接触多线程,可能问题有点幼稚,但是还是想问一下:条件变量相比较于直接使用互斥量,到底优势在哪里呢?查看了一些网上的资料,有的解释是通过条件变量的wait来使线程在没有必要执行的时候阻塞住,从而降低CPU的占用率。但是我发现用条件变量和不用条件变量对于CPU的占用率是差不多的。
比如说我用多线程和deque来模拟实现对消息队列的读写:(程序有点长,烦请过目)
//未使用条件变量
class MsgList
{
public:
void MsgWrite() //写线程
{
for (int i = 0; i < 10000; i++)
{
lock_guard<mutex> lck(m);
msgQue.push_back(i);
cout << "Write Message : " << i << endl;
}
}
void MsgRead() //读线程
{
while (true)
{
if (!msgQue.empty())
{
lock_guard<mutex> guard(m);
cout << "Read Message : " << msgQue.front() << endl;
msgQue.pop_front();
}
else
{
lock_guard<mutex> guard(m);
cout << "There is no Message !" << endl;
}
}
}
private:
deque<int> msgQue;
mutex m;
};
int main()
{
MsgList myMsg;
thread ReadThread(&MsgList::MsgRead, &myMsg);
thread WriteThread(&MsgList::MsgWrite, &myMsg);
ReadThread.join();
WriteThread.join();
return 0;
}
CPU占用率:
//使用条件变量(其他部分和前面一样)
class MsgList
{
public:
void MsgWrite()
{
for (int i = 0; i < 10000; i++)
{
unique_lock<mutex> lck(m);
msgQue.push_back(i);
cout << "Write Message : " << i << endl;
mycond.notify_one(); //唤醒wait
}
}
void MsgRead()
{
while (true)
{
unique_lock<mutex> lck(m);
mycond.wait(lck, [this]() {
return !msgQue.empty(); //条件变量
});
int ReadData = msgQue.front();
msgQue.pop_front();
cout << "Read Message : " << ReadData << endl;
}
}
private:
deque<int> msgQue;
mutex m;
condition_variable mycond;
CPU占用率:
由此我发现二者对CPU的影响是差不多的,那么使用条件变量的好处到底在哪呢?是我写的这段程序体现不出二者的差异
?还是我本身对条件变量的理解有误呢?
恳请指教,谢谢!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
上面的程序会有源源不断的资源push到队列中,当然区别就不大了。
如果是生产者的资源比较少,消费者需要进行长时间等待的时候,如果用互斥锁,消费者就需要不断轮询,占用资源;而用条件变量就可以实现等待。
另外,第一个程序里面
if (!msgQue.empty())
不一定是原子操作哦。举个例子,互斥锁轮询法:
输出:
说明读取线程轮询空转次数非常多
条件变量等待法
输出
这样就实现等待了