c++多线程唤醒notify_all与notify_one

*/
//单例设计模式:
/*
整个程序中某个或者某些特殊的类,他们只能创建一个对象(一般为数据共享)。
单例类,只能生成一个对向。
设计模式共享数据问题分析,解决
如果数据是只读的,多个线程同时调用没有问题,所以单例一般适合在只读数据上使用。
一般单例用来储存全局唯一变量。例如银行的货币的汇率。
建议:在创建其他线程之前,在主线程中就把单例的成员初始化和数据装载。
*/
//在子线程中创建单例
/*
面临问题:需要在我们自己创建的线程中创建MYCAS这个单例类对象,这样的线程最少两个、
所以GetInstance()这种成员函数需要互斥。
*/
//stable is the most important thing. 
//std::call_once()
/*
c++11,该函数的第二个参数是一个函数名,eg:a()
call_once功能时能够保证a()只被调用一次,具备互斥量这样的能力,而且效率比互斥量更高
但是需要和std::onec_flag这个标记结合使用。onec_flag是一个结构。
call_once()就是通过这个标记来决定对应的函数a()是否执行,调用call_once()成功后,call_once
就把这个标记设置为一种一调用状态
once_flag设置为一调用状态,那么对应的函数a()就不会再被执行了。
*/
#include<iostream>
#include<thread>
#include<mutex>
#include<list>
using namespace std;

mutex resource_mutex;//因为是静态函数引用,所以不能添加在类的private里。
std::once_flag g_flag;//标志符

class A {

	mutex my_mutex1;
	list<int>msgRecvQueue;
	std::condition_variable my_cond;
public:

	void inMsgRecvQueue()
	{
		for (int i = 0; i < 10000; i++)
		{
			
			//my_condi 中的lambda返回false,释放mutex1,这里就会得到mutex1
			std::unique_lock<std::mutex>inLock(my_mutex1);
			cout << "Insert a num in inMSG: " << i << endl;
			msgRecvQueue.push_back(i);
			my_cond.notify_one();//尝试把wait()的线程唤醒,wait()会再次尝试获取mutex的权限。一次只能唤醒一个线程。
			//不是1:1唤醒,两个可能同时争夺锁,in线程可能连续拿到两次锁,运行两次。
			my_cond.notify_all();//wake all the threads up.
			//std::chrono::milliseconds t (2000);
			//std::sl
		}
		return;
	}

	void outMsgRecvQueue()
	{
		int command = 0;
		while (true)
		{
			std::unique_lock<std::mutex>outlock(my_mutex1);
			//wait()用来等待一个东西
			/*
			如果第二个参数lambda表达式返回值是false,那么wait()将解锁互斥量,并堵塞到本行。
			堵塞到其他某个线程调用notify_one()成员函数为止。
			*/
			//如果wait中没有第二个参数
			/*
			等于返回false,解锁互斥量mutex1,堵塞线程,直到范湖notify_one一样
			*/

			//[this...return false;});是lambda表达式相当于一个返回结果的函数=一个变量参数
			my_cond.wait(outlock, [this] {//一个lambda表达式就是一个可调用对象(函数)
				if (!msgRecvQueue.empty())
					return true;
				return false;});
			command = msgRecvQueue.front();
			msgRecvQueue.pop_front();
			cout << "The number in the msg: " << command << ".ThreadID is "<<this_thread::get_id()<<endl;
			outlock.unlock();//We can unlock the unique lock,because of the flexiable of unique_lock.
			
		}
	}
};

int main()
{
	A myobj;
	std::thread myOutMsgObj(&A::outMsgRecvQueue, &myobj);//第二个参数是引用,才能保证线程里用的是同一个对象
	std::thread myOutMsgObj2(&A::outMsgRecvQueue, &myobj);//notify_all();
	std::thread myInMsgObj(&A::inMsgRecvQueue, &myobj);

	myInMsgObj.join();
	myOutMsgObj.join();

	return 0;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值