<二>、C++实现多线程的同步处理:控制ABC的输出顺序,输出10组,mutex+condition_variable

目录

场景:

核心代码:

输出效果:


接着上一篇,本篇实现更复杂一些的条件变量的处理。

若对题目要求还不是很清楚的,可以通过这个链接查看前一篇内容:

<一>、C++实现多线程的同步处理:控制ABC的输出顺序,输出10组,mutex+condition_variable-CSDN博客

场景:

这里面有个重要的概念是条件变量,顾名思义,需要加上条件来处理的场景就可以使用了,那么我们来研究以下需求的场景:

        需要3条线程输出不同的字符,分别为A、B、C,并且顺序要固定住:ABCABC...ABC[共10组],这样的情况下,只需要有一个计数器来统计字符的输出数量,通过这个计数器来对3取余,通过余数来当条件控制输出顺序即可。

        这个使用条件变量的方式,跟标志位有异曲同工之妙,并且不用来回变来变去的,只需要计数器不停递增即可。

        废话不多说了,上代码:

核心代码:

#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>
using namespace std;

//int g_flag = 0; // 全局标志位  0输出A,1输出B,2输出C
mutex g_mutex;
condition_variable g_conv; // 条件变量
int g_cnt = 0; // 计数器,初始化为0
void outA()
{
	/*for (int i = 0; i < 10;) {
		if (g_flag == 0) {  // 标志位为0 输出 A
			cout << "A"; // 输出目标字符A
			++i;	// 次数自增
			//g_mutex.lock();
			//unique_lock<mutex> ul(g_mutex); // 唯一锁,实例化时,自动加锁,离开作用域调析构自动解锁
			lock_guard<mutex> lg(g_mutex); // 守卫锁,也能起到自动加锁,自动解锁的作用
			g_flag = 1; // 修改标志位为1 让B输出
			//g_mutex.unlock();
		}
		// 若if条件不成立,就会一直死循环
		
	}*/
	/ 以下为条件变量相关代码
	for (int i = 0; i < 10; ++i) {
		unique_lock<mutex> ul(g_mutex); // 先创建一把唯一锁
		g_conv.wait(ul, [=] {return g_cnt % 3 == 0; }); // 条件变量等待的时候,当条件为真时 继续往下 余数为0继续,否则一直阻塞
		cout << "A"; // 输出目标字符
		++g_cnt;  // 计数器递增
		g_conv.notify_all(); // 唤醒所有
	}
}
void outB()
{
	/*for (int i = 0; i < 10;) {
		if (g_flag == 1) { // 标志位为1 输出 B
			cout << "B";
			++i;
			//g_mutex.lock();
			//unique_lock<mutex> ul(g_mutex);
			lock_guard<mutex> lg(g_mutex); // 守卫锁,也能起到自动加锁,自动解锁的作用
			g_flag = 2; // 修改标志位为2 接着让C输出
			//g_mutex.unlock();
		}
	}*/
	/ 以下为条件变量相关代码
	for (int i = 0; i < 10; ++i) {
		unique_lock<mutex> ul(g_mutex);
		g_conv.wait(ul, [=] {return g_cnt % 3 == 1; });
		cout << "B";
		++g_cnt;
		g_conv.notify_all();
	}
}
void outC()
{
	/*for (int i = 0; i < 10;) {
		if (g_flag == 2) {  // 标志位为2 输出 C
			cout << "C";
			++i;
			//g_mutex.lock();
			//unique_lock<mutex> ul(g_mutex);
			lock_guard<mutex> lg(g_mutex); // 守卫锁,也能起到自动加锁,自动解锁的作用
			g_flag = 0; // 修改标志位为0,让A输出
			//g_mutex.unlock();
		}
		
	}*/
	/ 以下为条件变量相关代码
	for (int i = 0; i < 10; ++i) {
		unique_lock<mutex> ul(g_mutex);
		g_conv.wait(ul, [=] {return g_cnt % 3 == 2; });
		cout << "C";
		++g_cnt;
		g_conv.notify_all();
	}

}

int main()
{
	thread tA(&outA); // A的线程
	tA.detach();
	thread tB(&outB); // B的线程
	tB.detach();
	thread tC(&outC); // C的线程
	tC.join(); // 最后一条线程需要用join来阻塞,防止主函数立即结束
    return 0;
}

输出效果:

        和之前没啥区别,不过效果更好控制,逻辑更简单易控。

优化后的代码,也可以查看这个帖子:

<三>、代码优化:C++实现多线程的同步处理:控制ABC的输出顺序,输出10组,mutex+condition_variable-CSDN博客

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五木大大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值