4-1 屏障(Barrier)

第3讲中的会合,只适合于两个线程之间,如果多个线程就不合适;
进一步推广会合解决方案。 每个线程都应该运行以下代码:
在这里插入图片描述
屏障的概念:屏障是多线程各自做自己的工作,如果某一线程完成了工作,就等待在屏障那里,直到其他线程的工作都完成了,再一起做别的事;举个通俗的例子:在百米赛跑里,比赛没开始之前,每个运动员都在赛场上自由活动,有的热身,有的喝水,有的跟教练谈论。比赛快开始时,准备完毕的运动员就预备在起跑线上,如果有个运动员还没准备完(除去特殊情况),他们就一直等,直到运动员都在起跑线上,裁判喊口号后再开始跑。这里的起跑线就是屏障,做完准备工作的运动员都等在起跑线,直到其他运动员也把准备工作做完!

1、屏障1解决方案

在这里插入图片描述
互斥锁信号量初始化

osSemaphoreId_t sem_mutex;
sem_mutex = osSemaphoreNew(1, 1, NULL);

屏障信号量初始化

osSemaphoreId_t sem_turnstile;
sem_turnstile = osSemaphoreNew(1, 0, NULL);

线程数初始化

int count = 0;

临界区代码

void critical_point()
{
	static int num = 0;
	num++;
	printf("num = %d \r\n", num);
}

线程1代码

osSemaphoreAcquire(sem_mutex, osWaitForever);
count++;
osSemaphoreRelease(sem_mutex);
if(count == 3)
{
	printf("rendezvous...\r\n");
	osSemaphoreRelease(sem_turnstile);
}
 else
     printf("thread 1 wait...\r\n");
osSemaphoreAcquire(sem_turnstile, osWaitForever); 
osSemaphoreRelease(sem_turnstile);
critical_point();

线程2代码

osSemaphoreAcquire(sem_mutex, osWaitForever);
count++;
osSemaphoreRelease(sem_mutex);
if(count == 3)
{
	printf("rendezvous...\r\n");
	osSemaphoreRelease(sem_turnstile);
}
 else
     printf("thread 2 wait...\r\n");
osSemaphoreAcquire(sem_turnstile, osWaitForever); 
osSemaphoreRelease(sem_turnstile);
critical_point();

线程3代码

osSemaphoreAcquire(sem_mutex, osWaitForever);
count++;
osSemaphoreRelease(sem_mutex);
if(count == 3)
{
	printf("rendezvous...\r\n");
	osSemaphoreRelease(sem_turnstile);
}
 else
     printf("thread 3 wait...\r\n");
osSemaphoreAcquire(sem_turnstile, osWaitForever); 
osSemaphoreRelease(sem_turnstile);
critical_point();

输出
在这里插入图片描述
可以看到在3个线程会合后,再执行临界区代码;
这种模式经常发生,即一对快速连续的wait()和signal()函数,它有一个名字,被称为旋转栅门(十字转门)(turnstile),因为它允许一次通过一个线程,并且可以锁定以阻止所有线程。
在其初始状态(零),旋转栅门被锁定。 第n个线程解锁它,然后所有n个线程都通过。

缺点:
读取互斥锁之外的count值似乎很危险。 在这种情况下,这不是问题,但一般来说,这可能不是一个好主意。
与此同时,您可能需要考虑以下问题:在第n个线程之后,旋转门处于什么状态?barrier屏障可能发出多于一次的信号吗?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值