MIT6.828_HW9_barriers

2024-01-11 02:18
文章标签 mit6.828 hw9 barriers

本文主要是介绍MIT6.828_HW9_barriers,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

MIT6.828_HW9_barriers

在这个任务中,我们使用由pthread库提供的条件变量来实现barrier。barrier 是一个应用程序点,必须所有线程到达这个点才能继续执行。条件变量是一种类似于xv6的 sleep 和 wakeup 的序列协调技术。

下载源码,编译执行。

$ gcc -g -O2 -pthread barrier.c
$ ./a.out 2
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 releases the mutex when called, and re-acquires the mutex before returning. 其需要一个互斥锁配合,以防止多个线程同时请求pthread_cond_wait()

barrier_init已经实现了,我们还需要实现barrier(),以致于不会再发生 panic。

有两个问题会使我们的任务变得复杂:

  • 必须处理一连串的 barrier call ,我们称之为一轮。bstate.round records the current round. You should increase bstate.round when each round starts.
  • 必须处理一个线程在其他线程退出 barrier 之前进行下一轮循环的情况。 In particular, you are re-using bstate.nthread from one round to the next. Make sure that a thread that leaves the barrier and races around the loop doesn’t increase bstate.nthread while a previous round is still using it.

实现过程

互斥量实现线程互斥,条件量用来实现线程同步。

在主函数里创建了 nthread(参数传入的) 个线程。

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);
}

使用pthread_cond_wait方式如下,为了避免由于线程并发执行所引起的资源竞争,所以要让每个线程互斥的访问公有资源,但是细心一下就会发现,如果while或者if判断的时候,不满足线程的执行条件,那么线程便会调用pthread_cond_wait阻塞自己,但是它持有的锁怎么办呢,如果他不归还操作系统,那么其他线程将会无法访问公有资源。pthread_cond_wait详解

    pthread _mutex_lock(&mutex)while或if(线程执行的条件是否成立)pthread_cond_wait(&cond, &mutex);线程执行pthread_mutex_unlock(&mutex);

每个线程循环 20000 次, 检查 i 是否等于 bstate.round, 实际就是不能让其他线程修改 bstate.round,应该是需要线程同步。pthread_join()函数会一直阻塞调用线程,直到指定的线程tid终止。英语是硬伤,一开始没理解清楚这个 HW 到底在表达什么,写出了以下代码(barrier()根本没改),也能 pass。按照我这种写法,是每个线程轮流执行了(失去了多线程的意义),后来发现是需要每个线程同步执行一次round++

static void *
thread(void *xa)
{long n = (long) xa;long delay;int i;pthread_mutex_lock(&bstate.barrier_mutex );if (bstate.round != 0) {pthread_cond_wait(&bstate.barrier_cond, &bstate.barrier_mutex);}for (i = 0; i < 20000; i++) {int t = bstate.round;// The assert triggers, because one thread leaves the barrier before the other thread has reached the barrier. assert (i == t);printf("thread %d\n", i);barrier();usleep(random() % 100);}bstate.round = 0;pthread_cond_broadcast(&bstate.barrier_cond);pthread_mutex_unlock(&bstate.barrier_mutex );
}

实际代码,修改barrier(),如下。

static void 
barrier()
{pthread_mutex_lock(&bstate.barrier_mutex );bstate.nthread++;if (bstate.nthread == nthread) {// 最后一个进程进入 执行 round++, 再唤醒其他进程。bstate.round++;bstate.nthread = 0;// 唤醒其他进程pthread_cond_broadcast(&bstate.barrier_cond);  } else {pthread_cond_wait( &bstate.barrier_cond, &bstate.barrier_mutex);}pthread_mutex_unlock(&bstate.barrier_mutex );
}

Questions

  1. 错误代码中pthread_cond_broadcast注释掉还是能 pass, why?

因为按照代码逻辑,线程根本不会进入 wait 里。第一个线程直接进入,第二个线程会卡在 lock_mutex上。

这篇关于MIT6.828_HW9_barriers的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/592824

相关文章

Zookeeper 进阶之——Zookeeper编程示例(如何使用Zookeeper实现屏障Barriers和队列Queues)...

[quote]原文:http://www.cnblogs.com/haippy/archive/2012/07/26/2609769.html [/quote] [b]引言[/b] 本文将告诉你如何使用 Zookeeper 实现两种常用的分布式数据结构,屏障(barriers) 和队列(queues),我们为此还分别实现了两个类:Barrier and Queue. 本文中的例子假设你已

操作系统入门系列-MIT6.828(操作系统工程)学习笔记(七)---- 系统调用函数与GDB(Lab: system calls)

系列文章目录 操作系统入门系列-MIT6.828(操作系统工程)学习笔记(一)---- 操作系统介绍与接口示例 操作系统入门系列-MIT6.828(操作系统工程)学习笔记(二)---- 课程实验环境搭建(wsl2+ubuntu+quem+xv6) 操作系统入门系列-MIT6.828(操作系统工程)学习笔记(三)---- xv6初探与实验一(Lab: Xv6 and Unix utilities)

操作系统入门系列-MIT6.828(操作系统工程)学习笔记(五)---- 操作系统的组织结构(OS design)

系列文章目录 操作系统入门系列-MIT6.S081(操作系统)学习笔记(一)---- 操作系统介绍与接口示例 操作系统入门系列-MIT6.828(操作系统工程)学习笔记(二)----课程实验环境搭建(wsl2+ubuntu+quem+xv6) 操作系统入门系列-MIT6.828(操作系统工程)学习笔记(三)---- xv6初探与实验一(Lab: Xv6 and Unix utilities) 操

操作系统入门系列-MIT6.828(操作系统工程)学习笔记(四)---- C语言与计算机架构(Programming xv6 in C)

系列文章目录 操作系统入门系列-MIT6.S081(操作系统)学习笔记(一)---- 操作系统介绍与接口示例 操作系统入门系列-MIT6.828(操作系统工程)学习笔记(二)----课程实验环境搭建(wsl2+ubuntu+quem+xv6) 操作系统入门系列-MIT6.828(操作系统工程)学习笔记(三)---- xv6初探与实验一(Lab: Xv6 and Unix utilities) 操

MIT6.828 Lab2-3 Sysinfo

目录 一、实验内容二、实验过程2.1 已有的代码2.2 需补充内容/kernel/kalloc.c修改(剩余内存计算的函数)/kernel/proc.c修改(统计进程数量的函数)/kernel/defs.h修改添加/kernel/sysinfo.c文件/kernel/syscall.h修改/kernel/syscall.c修改/user/user.h修改/user/usys.pl修改Make

Networked RFID Systems and Lightweight Cryptography: Raising Barriers to Product Counterfeiting

版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出版、作者信息和本声明。否则将追究法律责任。 http://blog.csdn.net/topmvp - topmvp The book consists of a collection of works on utilising the automatic identification technology provided

MIT6.828 实验环境安装教程

Thanks:mit6.828环境搭建 - 人云我不亦云的文章 - 知乎 https://zhuanlan.zhihu.com/p/489921553  sudo make && make install install -d -m 0755 "/share/qemu" install: 无法创建目录 “/share”: 权限不够 make: *** [Makefile:382:install-

[MIT6.828] LAB1中VBE图形界面测试总结

看到红色的Challenge就想挑战一把,于是搞了下VESA图形模式的编程。 科普知识: 什么是VBE? VBE的全称是VESA BIOS Extension。 什么是VESA? VESA的全称是Video Electronics Standards Association即视频电子标准协会,是由代表来自世界各地的、享有投票权利的超过165家成员公司的董事会领导的非盈利国际组织。 VESA致力于开

[MIT6.828]LAB1输入输出TAB字符的若干问题及总结

LAB1给代码中的'\t'的处理很简陋,直接把'\t'替换为5个空格,这和我们平时习惯有很大不同,所以要改造一下。 1、在kern/console.c cga_putc()函数中,可以看到'\t'case分支,把这个分支替换为如下代码: case '\t': do{ cons_putc(' '); }while(crt_pos%TAB_SIZE != 0); break; 其中的TAB_SIZE我

[MIT6.828] LAB4 PART A

Exercise 1.Implement round-robin scheduling in sched_yield() as described above. Don't forget to modify syscall() to dispatch sys_yield(). 修改kern/sched.c文件的sched_yield()函数 // Choose a user environme