线程并发同步--条件变量--conditional_variable

        同步:我的线程完成之后,你在进行下一个线程。可以理解为进货和卖货,即只有进或的线程结束后才可以执行卖货的这个线程。

        c++中提供了一个工具:conditional_variable。实现有两种方式,一种是condition_variable和conditon_variable_any。这里种方式使用时要配合互斥量使用,前者配合mutex。后者配合的多西只要能充当互斥就可以了。后者更加灵活。但是额外的开销也更大。

        这个condition_variable除了构造函数之外,wait这一函数也很重要。用于等待信号,既然有等待信号,那么也一定有发出信号,其函数为  notify_one  和  notify_all  。前者通知某一个线程,后者通知所有线程。

例程如下:线程1控制线程2,线程1修改一个值,修改完之后线程2才可以继续执行。

#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<Windows.h>

using namespace std;

mutex mtx;
condition_variable flag;


void thread1(void);
void thread2(void);
int c = -1;
int main(void)
{
	thread t1(thread1);
	thread t2(thread2);

	t1.join();
	t2.join();

	return 0;
}

void thread1(void)//线程1的作用是修改全局变量,然后线程2才可以运行
{
	int i = 0;
	Sleep(5000);
	while (1)
	{
		{
			lock_guard<mutex> lck(mtx);
			c = i++;
		}//花括号的作用是创建代码块
		//一个代码块结束之后就会自动释放里面的类
		//一旦释放了类就会自动调用析构函数解锁
		flag.notify_one();
		Sleep(1000);
	}
}

void thread2(void)
{
	while (1)
	{
		unique_lock<mutex> lck(mtx);
		//lock_guard这个模板是无法暂时性的释放锁的,所以这里不用lock_guard
		cout << "Thread2 waits for count: " << endl;
		flag.wait(lck);//wait在等待接受信号的同时还有一个作用就是暂时性的解锁
		cout << c << endl;
	}
}

运行结果如下:

         显然,大家看来了上面的代码必定是一头雾水,下面本文将从头刨析一次thread1和thread2:

第一步:

        显然因为线程1睡了5秒,是线程2霸占了玩具A, 但是线程2在霸占玩具A之后要等待信号A才能继续往下走,但是信号A由线程1发出,线程1只有霸占了玩具A才能发处信号A,显然,此时线程1无法霸占玩具A,因为其已经被线程2霸占了。

        如果线程2能在等待信号A的同时解除对玩具A的霸占就好了:此时就是flag.wait()有这个功能,可以在等待的同时解除霸占。如下:

 注意flag.wait()必须配合unique_lock()才能实现。

此时线程2解除了对玩具A的霸占,玩具A由线程1霸占:

        当线程2的while循环内第一次运行结束之后,开始进行第二次时,他想要霸占玩具A,但此时玩具A被线程1霸占 ,线程2无法进入第76行等待,也就无法进行下去了。

        那么此时就需要线程1把玩具A的霸占解除才行:使用代码段的方式:

        如上:加了一个花括号(63行,66行),在花括号里面的内容执行完后,自动释放花括号里面的数据,就把类给释放了,释放的同时调用了析构函数,就解锁即解除霸占。 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值