利用条件变量和互斥量循环打印ABC和1-100的错误情况
Posted Jqivin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用条件变量和互斥量循环打印ABC和1-100的错误情况相关的知识,希望对你有一定的参考价值。
、
循环打印ABC的错误情况
#include<iostream>
#include<mutex>
#include<condition_variable>
#include<queue>
using namespace std;
std::mutex mtx;
std::condition_variable cv;
int flg = 0;
void Print_A()
{
for (int i = 0; i < 5; i++)
{
std::unique_lock<std::mutex> locker(mtx);
if(flg != 0)
{
cv.wait(locker);
}
cout << "A";
flg = 1;
cv.notify_one();
}
}
void Print_B()
{
for (int i = 0; i < 5; i++)
{
std::unique_lock<std::mutex> locker(mtx);
if (flg != 1)
{
cv.wait(locker);
}
cout << "B";
flg = 2;
cv.notify_one();
}
}
void Print_C()
{
for (int i = 0; i < 5; i++)
{
std::unique_lock<std::mutex> locker(mtx);
if (flg != 2)
{
cv.wait(locker);
}
cout << "C ";
flg = 0;
cv.notify_one();
}
}
int main()
{
thread t1(Print_A);
thread t2(Print_B);
thread t3(Print_C);
t1.join(); t2.join(); t3.join();
return 0;
}
结果:
错误一
:使用了if导致错误
原因解释:
错误二
:使用了notify_one()函数。
如果只把if改成了while还是有问题,可能会导致死锁。如下面的情况
原因解释:
这是因为每次如果只唤醒一个线程,可能并不能唤醒我们想要的线程,就比如说,A执行完毕之后,应该唤醒B的,但是我们却唤醒了C,这就导致C也进行判断条件,从而执行cv.wait()进入了阻塞的状态。从而造成了死锁的局面。
最后,把if改成while,notify_one()改成notify_all()就可以了。
循环打印1-100的错误情况
先来看代码:
//利用三个线程打印1-100的数
int flg = 1;
std::mutex mtx;
std::condition_variable cv;
void fun1()
{
std::unique_lock<mutex> locker(mtx);
while (flg <=100)
{
while (flg % 3 != 1 && flg <=100)
{
cv.wait(locker);
}
cout << flg << " ";
flg += 1;
cv.notify_all();
}
}
void fun2()
{
std::unique_lock<mutex> locker(mtx);
while (flg <= 100 )
{
while (flg % 3 != 2 && flg <= 100)
{
cv.wait(locker);
}
cout << flg << " ";
flg += 1;
cv.notify_all();
}
}
void fun3()
{
std::unique_lock<mutex> locker(mtx);
while (flg <= 100 )
{
while (flg % 3 != 0 && flg <= 100)
{
cv.wait(locker);
}
cout << flg << " ";
flg += 1;
cv.notify_all();
}
}
int main()
{
thread t1(fun1);
thread t2(fun2);
thread t3(fun3);
t1.join(); t2.join(); t3.join();
return 0;
}
执行结果:
原因解释:当flg == 100的时候,执行fun1,执行完毕之后(此时fun2,fun3线程处于挂起状态)唤醒所有线程(此时fun2,fun3线程的while条件不满足-flg > 100,所以会执行输出flg);造成多输出两个。
修改:①可以将判断条件改为 <= 98;
②把wait()放在后面,代码如下:
int flg = 1;
std::mutex mtx;
std::condition_variable cv;
void fun1()
{
std::unique_lock<mutex> locker(mtx);
while (flg <= 100)
{
while (flg % 3 == 1 && flg <= 100)
{
cout << flg << " ";
flg += 1;
cv.notify_all();
}
cv.wait(locker);
}
}
void fun2()
{
std::unique_lock<mutex> locker(mtx);
while (flg <= 100)
{
while (flg % 3 == 2 && flg <= 100)
{
cout << flg << " ";
flg += 1;
cv.notify_all();
}
cv.wait(locker);
}
cv.notify_all(); //为了唤醒最后一个阻塞的线程
}
void fun3()
{
std::unique_lock<mutex> locker(mtx);
while (flg <= 100)
{
while (flg % 3 == 0 && flg <= 100)
{
cout << flg << " ";
flg += 1;
cv.notify_all();
}
cv.wait(locker);
}
}
结果:
以上是关于利用条件变量和互斥量循环打印ABC和1-100的错误情况的主要内容,如果未能解决你的问题,请参考以下文章