最近写6s081实验写到了lab7,发现了有一个barrier的概念很有意思,查了查资料总结了一下。

同步屏障可以用来管理一个应用中的不同线程,在一个应用中设立一个Barrier,当有指定数目的线程到达该Barrier时,唤醒所有处于SLEEPING状态的线程,继续执行。但是如果此时没有达到指定数目,则线程进入到SLEEPING状态。

以下的代码直接在linux中就能运行,用到了linux中的UNIX pthread threading library。你能够通过在命令行中输入man pthreads获取相关信息。

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
#include <pthread.h>static int nthread = 1;
static int round = 0;struct barrier {pthread_mutex_t barrier_mutex;pthread_cond_t barrier_cond;int nthread;      // Number of threads that have reached this round of the barrierint round;     // Barrier round
} bstate;static void
barrier_init(void)
{assert(pthread_mutex_init(&bstate.barrier_mutex, NULL) == 0);assert(pthread_cond_init(&bstate.barrier_cond, NULL) == 0);bstate.nthread = 0;
}static void
barrier()
{// YOUR CODE HERE//// Block until all threads have called barrier() and// then increment bstate.round.//pthread_mutex_lock(&(bstate.barrier_mutex));bstate.nthread++;if(nthread == bstate.nthread){bstate.nthread = 0;bstate.round++;pthread_cond_broadcast(&(bstate.barrier_cond));}else{pthread_cond_wait(&(bstate.barrier_cond),&(bstate.barrier_mutex));}pthread_mutex_unlock(&(bstate.barrier_mutex));}static void *
thread(void *xa)
{long n = (long) xa;long delay;int i;for (i = 0; i < 20000; i++) {int t = bstate.round;assert (i == t);barrier();usleep(random() % 100);}return 0;
}int
main(int argc, char *argv[])
{pthread_t *tha;void *value;long i;double t1, t0;if (argc < 2) {fprintf(stderr, "%s: %s nthread\n", argv[0], argv[0]);exit(-1);}nthread = atoi(argv[1]);tha = malloc(sizeof(pthread_t) * nthread);srandom(0);barrier_init();for(i = 0; i < nthread; i++) {assert(pthread_create(&tha[i], NULL, thread, (void *) i) == 0);}for(i = 0; i < nthread; i++) {assert(pthread_join(tha[i], &value) == 0);}printf("OK; passed\n");
}

代码中用到的一些锁:

pthread_mutex_t lock; // declare a lock
pthread_mutex_init(&lock, NULL); // initialize the lock
pthread_mutex_lock(&lock); // acquire lock
pthread_mutex_unlock(&lock); // release lock
pthread_cond_wait(&cond, &mutex); // go to sleep on cond, releasing lock mutex, acquiring upon wake up
pthread_cond_broadcast(&cond); // wake up every thread sleeping on cond

具体需要创建多少个线程通过命令行参数给出

$ make barrier
$ ./barrier 2
不同的设备需要通过自己的编译方式来编译

着重讲一讲barrier函数和barrier结构体


struct barrier {pthread_mutex_t barrier_mutex;pthread_cond_t barrier_cond;int nthread;      // Number of threads that have reached this round of the barrierint round;     // Barrier round
} bstate;static void
barrier()
{// YOUR CODE HERE//// Block until all threads have called barrier() and// then increment bstate.round.//pthread_mutex_lock(&(bstate.barrier_mutex));bstate.nthread++;if(nthread == bstate.nthread){bstate.nthread = 0;bstate.round++;pthread_cond_broadcast(&(bstate.barrier_cond));}else{pthread_cond_wait(&(bstate.barrier_cond),&(bstate.barrier_mutex));}pthread_mutex_unlock(&(bstate.barrier_mutex));}

在barrier函数中,最外层的锁是保证在我们对barrier进行操作时,不会有其他线程对barrier中的信息进行修改,因为bstate是公用的所以要避免竞态。

然后就是round和nthread这两个标志有什么用。

  • round是统一每个线程的轮次,注意thread函数中,thread在每次进入barrier前都要判断一下,自己持有的轮次是不是和当前bstate中的轮次是相同的。

为什们要这样做呢?假如说现在我有十个线程,但是barrier只要求同步5个,在线程每次轮询的时候都要将当前的轮次记录,但是在进入barrier前有可能已经有5个线程进入了,导致此时barrier所有的线程都运行了,此时持有上个轮次的线程就不应该进入barrier。

  • nthread是用于记录进入barrier的线程的数目,用于在barrier中判断线程是进入SLEEPING还是唤醒。

同步屏障Barrier相关推荐

  1. android同步方法和对象的区别是什么,(4.1.10.8)Android Handler之同步屏障机制(sync barrier)...

    一.概述 简单理解为 异步消息插队并优先执行. 场景:排队买票 先来了一个普通用户来排队,买完票走了. 后面又来了一个VIP用户A来买票 就一直站在卖窗口这里 也不走(ps:添加屏障 ) 紧接者又来了 ...

  2. Handler sync barrier(同步屏障)

    Handler中的Message可以分为两类:同步消息.异步消息.消息类型可以通过以下函数得知 //Message.java public boolean isAsynchronous() {retu ...

  3. java多线程 门闩_Java线程与并发编程实践----同步器(倒计时门闩,同步屏障)...

    Java提供的synchronized关键字对临界区进行线程同步访问.由于基于synchronized很难 正确编写同步代码,并发工具类提供了高级的同步器.倒计时门闩(countdown latch) ...

  4. 并发工具类(二)同步屏障CyclicBarrier

    前言   JDK中为了处理线程之间的同步问题,除了提供锁机制之外,还提供了几个非常有用的并发工具类:CountDownLatch.CyclicBarrier.Semphore.Exchanger.Ph ...

  5. 高级同步器:可重用的同步屏障Phaser

    引自:https://shift-alt-ctrl.iteye.com/blog/2302923 在JAVA 1.7引入了一个新的并发API:Phaser,一个可重用的同步barrier.在此前,JA ...

  6. Java多线程同步屏障计算_Java多线程之CountDownLatch和CyclicBarrier同步屏障的使用

    一:CountDownLatch CountDownLatch是一个执行 完成任务线程数 的 倒数计数器.我们考虑这种情况:士兵晨练,必须全队士兵集合完毕才开始跑步.用程序描述就:在晨练线程中,逐个启 ...

  7. Java并发编程的艺术(八)——闭锁、同步屏障、信号量详解

    1. 闭锁:CountDownLatch 1.1 使用场景 若有多条线程,其中一条线程需要等到其他所有线程准备完所需的资源后才能运行,这样的情况可以使用闭锁. 1.2 代码实现 // 初始化闭锁,并设 ...

  8. Handler机制——同步屏障

    一.消息种类 关于Handler机制的基本原理不了解可以看这里: Handler机制源码解析. Message分为3种:普通消息(同步消息).屏障消息(同步屏障)和异步消息.我们通常使用的都是普通消息 ...

  9. Android:同步屏障的简单理解和使用

    同步屏障的简单理解和使用 1.背景 2.何为同步屏障? 2.1. 发送屏障消息--postSyncBarrier 2.2.发送异步消息 2.3.处理消息 2.4.移除屏障消息--removeSyncB ...

最新文章

  1. 遗传算法 Genetic Algorithm
  2. C#(Winform)实现条码打印
  3. 3——PHP 简单运算符的使用
  4. python 调用c++ 回调函数
  5. 在当前进程下取得当前登陆用户
  6. 利用who,w,ps和top等指令查看linux下的进程执行情况.,UNIXLINUX操作系统实验指导书...
  7. Linux中grep命令 常用选项
  8. C语言基础语言总结(二)
  9. c语言用指针两个字母交换,c语言指针基础之用指针交换两个数(代码实例)
  10. iOS12系统图片heic如何在电脑上查看
  11. 618哪家空调最受欢迎?格力奥克斯互撕 友商却笑到最后
  12. ES6、TYPESCRIPT、ATSCRIPT和BABEL是什么玩意儿
  13. MSSQL 同步两个数据库的示例
  14. 牛客网——与7无关的数
  15. 手把手教你在VM虚拟机上安装windows11
  16. 微信小程序开发笔记——开发者工具介绍
  17. 3.1 机器学习 --- 决策树
  18. 用python做一个数据查询软件_使用Python实现NBA球员数据查询小程序功能
  19. 各类学生机万能卸载攻略
  20. wget 下载失败,使用“--no-check-certificate”,/C=US/O=Let‘s Encrypt/CN=R3” 颁发的证书

热门文章

  1. Scaled-YOLOv4 简单学习笔记
  2. 非支配排序遗传算法c语言,非支配排序遗传算法(NSGA)的研究与应用
  3. 腾讯手游助手王者服务器,腾讯手游助手王者荣耀正在定位无法进入的解决教程...
  4. 设计婴儿、人体冷冻... 颠覆未来的8种技术!网友:太可怕了
  5. mysql数据库 菜鸟_数据库-MySQL入门
  6. 再看罗永浩对质王自如
  7. 2017年东南大学计算机博士申请经验分享
  8. 中级软件设计师-软考心得
  9. 英勇青铜5基金个人策略
  10. MT7621_基础篇(1) 芯片资料了解 一