MIT6.828学习之homework9:Barriers
在本作业中,我们将探讨如何使用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相关推荐
- MIT6.828学习之Lab1
一.概要 了解x86汇编语言,学会用QEMU模拟x86环境,学会用GDB调试 BIOS负责执行基本的系统初始化,从某些适当的位置(如 floppy disk(软盘), hard disk, CD-RO ...
- MIT6.828学习之homework2:shell
之前同学提起,能区分得开xv6与JOS吗?才发现真不知道,赶紧查了查: 1.extended inspection of xv6, a traditional O/S xv6,一个传统的操作系统的扩展 ...
- MIT6.828课程学习初步
MIT6.828课程学习初步 MIT6.828课程是1门比较好的操作系统原理课程,通过动手实践xv6操作系统来熟悉原理. [ 课程网站 ] 原先是想从Linux内核开始看起,但是看了一段时间,由于都是 ...
- Mit6.S081学习记录
Mit6.S081学习记录 前言 一.课程简述 二.课程资源 1,课程主页 2,参考书 3,实验环境 三.学习过程 Mit6.S081-实验环境搭建 Mit6.S081-GDB使用 Mit6.S081 ...
- MIT6.828——LAB1:Booting a PC
MIT6.828--LAB1:Booting a PC Part1:PC Bootstrap 练习1: 熟悉X86汇编语言 The PC's Physical Address Space 电脑的物理地 ...
- MIT6.828课程JOS在macOS下的环境配置
本文将介绍如何在macOS下配置MIT6.828 JOS实验的环境. 写JOS之前,在网上搜寻JOS的开发环境,很多博客和文章都提到"不是32位linux就不好配置,会浪费大量时间在配置环境 ...
- MIT6.828 32位操作系统笔记(3)----系统的启动和初始化
MIT EDU 6.828 实验源代码 分类 MIT6.828 32位操作系统实验笔记 实验完善代码 LAB2-4下载链接 提取码:79t8 系统的启动过程 物理内存的分布 首先分析PC 开机以后的默 ...
- MIT6.828 异常和中断学习笔记
csapp分类: Exception(异常),分为同步异常和异步异常,本质都是将控制交给kernel解决的. 异步异常,也称为中断(Interrupt)指由处理器外部的事引起的,计时器中断和I/O中断 ...
- MIT6.824_2021_学习总结 分布式常见知识点
目录 知识点 分布式系统原则 CAP BASE ACID和BASE的区别与联系 分布式一致性 线性一致性 顺序一致性 因果一致性 FIFO 一致性 最终一致性 分布式共识算法 Paxos: Raft: ...
最新文章
- ListView style
- textarea中的换行符
- c语言使用函数累加由n个a构成的整数之和,c 语言使用函数累加由n个a构成的整数之和...
- 新建Exchange服务器 Outlook端收发邮件报错:0x80040201
- Python + OpenCV 太好玩了,可惜你可能还不会
- express.static 和 lit-html
- 全网都在看的Jmeter精选原创文章
- 多媒体计算机是多媒体教室的核心部件,浅析多媒体教室的设备配置
- 【特色团队采访】1+1+1>3?看新人团队如何高效合作
- git常用命令与常见问题解决办法
- 基于机器视觉的铁片轮廓检测
- Linux之远程连接服务器ssh、telnet
- android camera调试打印信息,Android : 高通平台Camera调试
- 瑞星客户端卸载操作手册
- 抖音04开头xgorgon、xlog、设备注册算法
- 【风变编程】第五课笔记
- getTextSize()和putText()
- C++的get()函数与getline()函数使用详解
- GetMACAddress 在java查询中获取 MACA 地址
- 国产操作系统逐步强大,Linux操作系统成为主流