2019/12/24 03-Barrier

barrier可以理解为是屏障,是阻碍你前行的
在这里插入图片描述
3.2引入的新功能,parties参与方,action做什么动作
在这里插入图片描述
在这里插入图片描述等待数,要几个人参与,等待几个人在这里插入图片描述在这里插入图片描述
类似赛车,开始都在起点等,等都到齐了再跑,需要等到所有参赛方都到齐了才开始,拦起来,等待所有的参与方到齐,这就是barrier
在这里插入图片描述
wait不超时
在这里插入图片描述
启动一个线程,但是要求参与方是三个在这里插入图片描述
等到条件成熟才能结束
在这里插入图片描述在这里插入图片描述
改成2就是2个参与方
在这里插入图片描述
条件满足这一句就执行了,都跑起来了,等待的就没几个在这里插入图片描述
参与方不够是可以看到n.waiting的,参与方等待数一旦达到,会立即执行

barrier,可以在一些场景下:
比如有些事可以并发一起做,但是这几个条件满足以后,才能做下面的事情,第一阶段4个事情做完都在wait,条件触发进行第二阶段的事情
在这里插入图片描述
这是继续向后执行,但是全出问题了在这里插入图片描述
因为一旦barrier.abort()打破以后,下面一句抛出异常,brokenbarriererror,一个破了的barrier,表示屏障是一个打破的状态在这里插入图片描述
在后面再进行修改,broken是true了
在这里插入图片描述
这样加了以后,当i=0,1,2正好第三个的时候打破了,打破了之后,barrier处于一种状态,叫broken状态,这种状态barrier是不能正常工作的,也就是直接访问get,是get不了的在这里插入图片描述
要修复下barrier
在这里插入图片描述
reset是恢复到初始的状态的在这里插入图片描述
起来6个线程,两个在等,barrier是恢复了,但是前面的异常已经抛出去了,前面的在你打破到恢复之间的线程,这些线程wait了就崩了在这里插入图片描述
出了问题,现在语句里也没有上下文管理,try,finally在这里插入图片描述
起9个线程,456,789都可以,崩掉三个,有些任务可以完成在这里插入图片描述
正好,这样就没有等待了,中间是可以把barrier,broken的
在这里插入图片描述
barrier在使用的时候,由于某种情况,可能会导致barrier 变成broken了,在适当的情况下,需要reset,有下面两个方法使用,但是一般都不使用,barrier只要是brokern状态都无法正常使用在这里插入图片描述
如果要使用的话,加try和finally在这里插入图片描述在这里插入图片描述抛出的异常现在在threading里面,不在builtin里面,这个异常属于线程中的barrier要使用的,是放在threading模块中的在这里插入图片描述
runtimeerror异常的祖先类就是exception在这里插入图片描述
这就是运行时产生的异常,barrier是大家都在等,等到参与方都齐了,然后一起开始工作,barrier不关心线程是否重新使用,只关心,要不要wait,按照现在调用,wait方都会阻塞,只关心等的人够不够
在这里插入图片描述
现在修改成这样
wait(1)秒,这就是一种超时的判断。超时就抛异常
在这里插入图片描述在这里插入图片描述
执行这一句说明抛出异常了

在这里插入图片描述
如果在指定的时间内没有等到参与方都到齐,当前barrier直接broken,如果不reset是没办法继续执行的,不reset,相当于没有消耗掉barrier,是不能用的

一旦通过某些语句,导致了barrier超时了,这个barrier就处于一种不能工作的broken状态,必须手动调用reset恢复,否则barrier不能用 了,不管是手动打破还是超时打破,barrier不能正常工作,要使用barrier就必须reset,将它重置,这个时候broken就是false(说明现在不是broken,说明现在是可以工作的,barrier现在是一种正常状态)

barrier的超时是回抛出异常的,不仅会抛出异常,还会把当前barrier打破,处于broken状态,而且broken状态必须reset,没有reset恢复不了(barrier,就abort和n.waiting,构造方法,reset,就这几个)在这里插入图片描述在这里插入图片描述
wait会返回一个id,相当于永久阻塞,如果wait成功,返回一个id,如果wait不成功,就不返回id(wait超时,要么false,要么不成功)
一直等,等到返回barrier_id 为止,要么抛出异常,刚才打印看到的数值就是barrier_id
在这里插入图片描述在这里插入图片描述
broken状态,必须reset来使用,如果broken,状态就不能abort使用,会抛出brokenBarrierError异常在这里插入图片描述在这里插入图片描述在这里插入图片描述wait方法,是超时发生之后,屏障就处于broken状态,borken状态只能由reset恢复在这里插入图片描述在这里插入图片描述
只有超时,没有阻塞不阻塞的东西
在这里插入图片描述
这个方法可能产生这个异常,当下已经是broken,这个就没法用
在这里插入图片描述
现在修改成这样
在这里插入图片描述
查看这个一个线程,线程,启动,wait两秒,打印里面的波浪线在这里插入图片描述
如果没等到,不是返回一个barrier_ID
在这里插入图片描述在这里插入图片描述
barrier应用
并发初始化,
所有线程都必须初始化完成后,才能继续工作,例如运行前加载数据、检查,如果这些工作没完成,就开始运行,将不能正常工作。
10个线程做10种工作准备,每个线程负责一种工作,只有这10个线程都完成后,才能继续工作,先完成的要等待后完成的线程。
在这里插入图片描述
把123做完才能做到4FF
**前面的这几部工作,都需要wait,读取文件,建立数据库链接都要做好,才能对外服务,现在的这些准备工作可以并行处理,处理完,条件都具备了,才能真正运行下一步,这时候需要barrier来处理,失败了就abort,所有的barrier,wait不下去了,刚才等,如果把屏障打破了,就没必要等了,屏障就从当前的broken状态变成非broken状态,等待就没有用了
**
这些线程本来在等,由于某一个线程执行失败之后,手动barrier来abort,如果前两步做好了,数据库链接没成功,就直接把barrier 变abort了(刚才在等的已经没有意义了,也会抛出异常,因为在barrier上去wait,wait以后就会抛出异常,brokenbaiiererror,然后该对线程做什么处理就做什么处理,最后整个程序退出)
在这里插入图片描述
并行处理后,当条件都具备进行下一步

还有一种就是工作量的问题,有10个完成6个即可
barrier会抛出异常,异常恢复,需要reset,不reset,回去不了,barrier就处于一种异常状态,broken状态,原来等待也会出问题,是跟event相关的
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个错误通常是因为在Windows上使用了错误的入口点(entry point)导致的。在Windows上,C程序的入口点应该是`int main()`而不是`WinMain`。请确保您的代码中有正确的`int main()`函数,并且没有定义`WinMain`函数。 以下是一个简单的示例程序,用于计算n个数字的总和,您可以尝试运行它: ```c #include <stdio.h> #include <omp.h> int main() { int n = 1000000; // 输入要计算总和的数字个数 int* numbers = (int*)malloc(n * sizeof(int)); // 初始化数字数组 for (int i = 0; i < n; i++) { numbers[i] = i + 1; } // 使用OpenMP reduction子句的算法 double start_time = omp_get_wtime(); int sum1 = 0; #pragma omp parallel for reduction(+:sum1) for (int i = 0; i < n; i++) { sum1 += numbers[i]; } double end_time = omp_get_wtime(); printf("使用OpenMP reduction子句的总和: %d\n", sum1); printf("使用OpenMP reduction子句的运行时间: %lf 秒\n", end_time - start_time); // 让每个线程计算部分总和并累加的算法 start_time = omp_get_wtime(); int num_threads = omp_get_max_threads(); int* partial_sums = (int*)malloc(num_threads * sizeof(int)); #pragma omp parallel { int thread_id = omp_get_thread_num(); int num_elements_per_thread = n / num_threads; int start = thread_id * num_elements_per_thread; int end = start + num_elements_per_thread; int partial_sum = 0; for (int i = start; i < end; i++) { partial_sum += numbers[i]; } partial_sums[thread_id] = partial_sum; #pragma omp barrier if (thread_id == 0) { int sum2 = 0; for (int i = 0; i < num_threads; i++) { sum2 += partial_sums[i]; } end_time = omp_get_wtime(); printf("使用每个线程计算部分总和并累加的总和: %d\n", sum2); printf("使用每个线程计算部分总和并累加的运行时间: %lf 秒\n", end_time - start_time); } } free(numbers); free(partial_sums); return 0; } ``` 请确保您的代码中包含了正确的`int main()`函数,并且没有定义`WinMain`函数。如果问题仍然存在,请提供您的代码,我将尽力帮助您解决问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值