基于C++11的条件变量实现多线程互斥

1 篇文章 0 订阅

写在开头
        前端时间在工作中遇到一个使用场景,要设计三个线程分别执行执行三个任务,并且需要按照1,2,3的顺序循环执行。研究了一下C++中常用的互斥机制,最后使用C++11中的条件变量实现了上述业务场景的需求。关于C++11中的条件变量,本文不做详细介绍,直接上代码实现,代码可直接编译运行。

/*
	基于C++11的条件变量实现多线程同步的功能
*/

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

//线程运行的条件
enum ThreadRunConditionType : unsigned short
{
	ThreadRunCondition1,//线程1运行的条件
	ThreadRunCondition2,//线程2运行的条件
	ThreadRunCondition3,//线程3运行的条件
};

//条件类型
ThreadRunConditionType ThreadRunCondition;

//控制三个线程按1,2,3顺序依次执行的条件变量
std::condition_variable condiVar;
std::mutex mutex;


//最后一个线程执行完后,通知第一个线程重新开始执行的条件变量
std::condition_variable condiVar2;
std::mutex mutex2;


//控制循环执行次数
#define LOOP_RUNNING_NUMBERS	0xffffffff
bool isRunning(int index)
{
	return (index <= LOOP_RUNNING_NUMBERS);
}

void MyThreadProc1(std::string guid)
{
	unsigned int index = 0;
	while (1)
	{
		{
			//do somethings in thread1
			std::unique_lock<std::mutex> lock(mutex);
			std::cout << guid.c_str() << " : " << index++ << std::endl;
			
			//线程1任务执行完成后,更新线程执行条件为线程2的条件,并通知其他线程
			ThreadRunCondition = ThreadRunCondition2;	

			condiVar.notify_all();
		}
		//condiVar.notify_all();

		{
			//等待线程3执行结束后的通知
			std::unique_lock<std::mutex> lock(mutex2);
			//condiVar2.wait_for(lock, std::chrono::milliseconds(1000));
			condiVar2.wait(lock);
		}

		if (!isRunning(index))
		{
			break;
		}
	}
}

void MyThreadProc2(std::string guid)
{
	unsigned int index = 0;
	while (1)
	{
		{
			//等待条件变量满足线程2执行的条件
			std::unique_lock<std::mutex> lock(mutex);
			condiVar.wait(lock, [] {return (ThreadRunCondition2 == ThreadRunCondition); });
			//condiVar.wait_for(lock, std::chrono::milliseconds(100), [] {return (ThreadRunCondition2 == ThreadRunCondition); });
			
			//do somethings in thread2
			std::cout << guid.c_str() << " : " << index++ << std::endl;
			ThreadRunCondition = ThreadRunCondition3;

			condiVar.notify_all();
		}
		//将线程执行条件更新为满足线程3的条件,并发出条件变量释放的通知
		//condiVar.notify_all();

		if (!isRunning(index))
		{
			break;
		}
	}
}

void MyThreadProc3(std::string guid)
{
	unsigned int index = 0;
	while (1)
	{
		{
			//等待条件变量满足线程3执行的条件
			std::unique_lock<std::mutex> lock(mutex);
			condiVar.wait(lock, [] {return (ThreadRunCondition3 == ThreadRunCondition); });
			
			//do somethings in thread2
			std::cout << guid.c_str() << " : " << index++ << std::endl << std::endl;
			
			//将线程执行条件更新为满足线程1的条件
			ThreadRunCondition = ThreadRunCondition1;
		}

		{
			//通知线程1,可以重新开始执行新一轮的任务
			std::unique_lock<std::mutex> lock(mutex2);
			condiVar2.notify_all();
		}

		if (!isRunning(index))
		{
			break;
		}
	}
}

int main()
{
	std::string guid1 = "testthrea#####1";
	std::string guid2 = "testthrea$$$$$2";
	std::string guid3 = "testthrea&&&&&3";

	std::thread th1(MyThreadProc1, guid1);
	std::thread th2(MyThreadProc2, guid2);
	std::thread th3(MyThreadProc3, guid3);

	th1.join();
	th2.join();
	th3.join();

	system("pause");
    return 0;
}

运行结果如下图:

测试循环运行1000次顺序都是正常的,博主也作过无限次数运行,运行结果顺序一直正常。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值