在本作业中,我们将探讨如何使用pthread库提供的条件变量来实现barrier。barrier是应用程序中的一个点,在这个点上,所有线程都必须等待,直到所有其他线程也到达该点。条件变量是一种序列协调技术,类似于xv6的sleep和wakeup

下载barrier.c,然后在你的手提电脑或Athena machine上编译:

$ gcc -g -O2 -pthread barrier.c
$ ./a.out 2
Assertion failed: (i == t), function thread, file barrier.c, line 55.

2指定在barrier上同步的线程数(barrier.c中的nthread)。每个线程都处于一个紧密的循环中。在每个循环迭代中,一个线程调用barrier(),然后休眠若干微秒。assert触发,因为一个线程在另一个线程到达barrier之前离开barrier。理想的行为是所有线程都应该阻塞,直到nthread调用barrier(这里的nthread是不是就是线程号i==nthread的那个线程?错,应该是本轮调用barrier的线程总数bstate.nthread)。

你的目标是实现这理想的行为。除了您以前见过的锁原语之外,您还需要以下新的pthread原语(有关详细信息,请参阅man pthreads):

//函数pthread_cond_wait()使线程阻塞在一个条件变量上
pthread_cond_wait(&cond, &mutex);  // go to sleep on cond, releasing lock mutex
pthread_cond_broadcast(&cond);     // wake up every thread sleeping on cond

pthread_cond_wait被调用时释放mutex,并在返回前重新获取mutex。

我们已经给出了barrier_init()。您的工作是实现barrier(),这样就不会发生恐慌。我们已经为你们定义了struct barrier;它的字段供您使用。

有两个问题会使你的任务复杂化:

  • 你必须处理一连串的barrier calls,每一连串我们都称之为一轮(这里的一轮是指所有的线程都调用一次barrier?对)。bstate.round记录了当前轮。每个轮开始时你都应该增加bstate.round。
  • 您必须处理这样一种情况:一个线程在其他线程退出barrier之前绕着循环运行。特别是,你正在重新使用bstate.nthread从一轮到下一轮。确保离开barrier并绕循环运行的线程不会增加bstate.nthread,当上一轮仍然在使用它。
static void
barrier()
{pthread_mutex_lock(&bstate.barrier_mutex);bstate.nthread++;printf("in round %d as %d\n ",bstate.round, bstate.nthread);if(bstate.nthread!=nthread)pthread_cond_wait(&bstate.barrier_cond, &bstate.barrier_mutex);else{bstate.round++;bstate.nthread=0;//printf("The %d start\n",bstate.round);//pthread_mutex_unlock(&bstate.barrier_mutex); why can't?pthread_cond_broadcast(&bstate.barrier_cond);//pthread_mutex_unlock(&bstate.barrier_mutex); why can't?}pthread_mutex_unlock(&bstate.barrier_mutex);}

使用一个、两个和多个线程测试代码。

//使用三个线程,并自定义输出
...
in round 19996 as 1
in round 19996 as 2
in round 19996 as 3
in round 19997 as 1
in round 19997 as 2
in round 19997 as 3
in round 19998 as 1
in round 19998 as 2
in round 19998 as 3
in round 19999 as 1
in round 19999 as 2
in round 19999 as 3
OK; passed

主要问题

1.要明白这里的主要任务是:每一轮bstate.round是要每一个线程都调用一遍barrier,调用之后阻塞在条件变量cond上,当本轮最后那个线程(即n==nthread bstate.nthread==nthread)调用完barrier后,下一轮就要开始了,btate.round++并且所有阻塞在cond上的线程都应该释放。

2.条件变量cond互斥锁mutex在这里各起什么作用?怎么使用?
cond就相当于一个"队列"一样,如果本轮还有线程没调用barrier,那当前线程应该阻塞在cond上,即进"队列"。当本轮最后那个线程调用了barrier,那意味着下一轮就要开始了,bstate.nthread=0,bstate.round++,然后将所有阻塞在cond中的进程唤醒,即全部出"队列"。
而mutex的使用,主要是为了保护bstate.nthread与bstate.round,避免多个线程同时修改这两个变量。

3.我代码中,如果pthread_mutex_unlock放在else里面就会发生死锁,为什么?
按道理如果没进else就会在pthread_cond_wait中把mutex释放,除非存在调用pthread_cond_wait失败的情况导致mutex没释放。

MIT6.828学习之homework9:Barriers相关推荐

  1. MIT6.828学习之Lab1

    一.概要 了解x86汇编语言,学会用QEMU模拟x86环境,学会用GDB调试 BIOS负责执行基本的系统初始化,从某些适当的位置(如 floppy disk(软盘), hard disk, CD-RO ...

  2. MIT6.828学习之homework2:shell

    之前同学提起,能区分得开xv6与JOS吗?才发现真不知道,赶紧查了查: 1.extended inspection of xv6, a traditional O/S xv6,一个传统的操作系统的扩展 ...

  3. MIT6.828课程学习初步

    MIT6.828课程学习初步 MIT6.828课程是1门比较好的操作系统原理课程,通过动手实践xv6操作系统来熟悉原理. [ 课程网站 ] 原先是想从Linux内核开始看起,但是看了一段时间,由于都是 ...

  4. Mit6.S081学习记录

    Mit6.S081学习记录 前言 一.课程简述 二.课程资源 1,课程主页 2,参考书 3,实验环境 三.学习过程 Mit6.S081-实验环境搭建 Mit6.S081-GDB使用 Mit6.S081 ...

  5. MIT6.828——LAB1:Booting a PC

    MIT6.828--LAB1:Booting a PC Part1:PC Bootstrap 练习1: 熟悉X86汇编语言 The PC's Physical Address Space 电脑的物理地 ...

  6. MIT6.828课程JOS在macOS下的环境配置

    本文将介绍如何在macOS下配置MIT6.828 JOS实验的环境. 写JOS之前,在网上搜寻JOS的开发环境,很多博客和文章都提到"不是32位linux就不好配置,会浪费大量时间在配置环境 ...

  7. MIT6.828 32位操作系统笔记(3)----系统的启动和初始化

    MIT EDU 6.828 实验源代码 分类 MIT6.828 32位操作系统实验笔记 实验完善代码 LAB2-4下载链接 提取码:79t8 系统的启动过程 物理内存的分布 首先分析PC 开机以后的默 ...

  8. MIT6.828 异常和中断学习笔记

    csapp分类: Exception(异常),分为同步异常和异步异常,本质都是将控制交给kernel解决的. 异步异常,也称为中断(Interrupt)指由处理器外部的事引起的,计时器中断和I/O中断 ...

  9. MIT6.824_2021_学习总结 分布式常见知识点

    目录 知识点 分布式系统原则 CAP BASE ACID和BASE的区别与联系 分布式一致性 线性一致性 顺序一致性 因果一致性 FIFO 一致性 最终一致性 分布式共识算法 Paxos: Raft: ...

最新文章

  1. ListView style
  2. textarea中的换行符
  3. c语言使用函数累加由n个a构成的整数之和,c 语言使用函数累加由n个a构成的整数之和...
  4. 新建Exchange服务器 Outlook端收发邮件报错:0x80040201
  5. Python + OpenCV 太好玩了,可惜你可能还不会
  6. express.static 和 lit-html
  7. 全网都在看的Jmeter精选原创文章
  8. 多媒体计算机是多媒体教室的核心部件,浅析多媒体教室的设备配置
  9. 【特色团队采访】1+1+1>3?看新人团队如何高效合作
  10. git常用命令与常见问题解决办法
  11. 基于机器视觉的铁片轮廓检测
  12. Linux之远程连接服务器ssh、telnet
  13. android camera调试打印信息,Android : 高通平台Camera调试
  14. 瑞星客户端卸载操作手册
  15. 抖音04开头xgorgon、xlog、设备注册算法
  16. 【风变编程】第五课笔记
  17. getTextSize()和putText()
  18. C++的get()函数与getline()函数使用详解
  19. GetMACAddress 在java查询中获取 MACA 地址
  20. 国产操作系统逐步强大,Linux操作系统成为主流

热门文章

  1. 计算机二级是win7,计算机二级等考宝典
  2. SAP 的成本中心与利润中心的关系
  3. 转载:你的同龄人正在抛弃你
  4. [JIRA] 从3.6.2旧版升级到新版6.0.8的详细过程
  5. PAT A1095 Cars on Campus ——一夜鱼龙舞
  6. 雅点ps证件之星插件扩展面板完美破解版
  7. 标定中的zoomfocus
  8. FastDFS的三大误解
  9. 1.FPGA基础知识
  10. 教大家微信里投票的怎么刷票及微信投票怎么免费刷票攻略