利用条件变量和互斥量循环打印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);
	}
}

结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值