【MIT 6.S081】Lab7: Multithreading

这篇具有很好参考价值的文章主要介绍了【MIT 6.S081】Lab7: Multithreading。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本Lab比较简单,就是为xv6添加一个用户级的多线程功能,然后熟悉一下Linux下多线程编程。
笔者用时约2h

Uthread: switching between threads

这一部分的代码不涉及内核代码,所以也比较简单,根据提示修改user/uthread.c中的代码即可。仿照内核中进程转换函数swtch的实现即可。首先,添加一个context上下文结构体用于保存被调用者保存寄存器(从kernel/proc.h中复制过来就行啦)。

struct context {
  uint64 ra;
  uint64 sp;

  // callee-saved
  uint64 s0;
  uint64 s1;
  uint64 s2;
  uint64 s3;
  uint64 s4;
  uint64 s5;
  uint64 s6;
  uint64 s7;
  uint64 s8;
  uint64 s9;
  uint64 s10;
  uint64 s11;
};

并且为thread添加一个context字段

struct thread {
  char       stack[STACK_SIZE]; /* the thread's stack */
  int        state;             /* FREE, RUNNING, RUNNABLE */
  struct context context;
};

然后需要仿照swtch函数(定义在kernel/swtch.S中)实现一个thread_switch函数(定义在user/uthread_switch.S中),其实也就是复制过来就好啦

thread_switch:
	/* YOUR CODE HERE */
	
	sd ra, 0(a0)
	sd sp, 8(a0)
	sd s0, 16(a0)
	sd s1, 24(a0)
	sd s2, 32(a0)
	sd s3, 40(a0)
	sd s4, 48(a0)
	sd s5, 56(a0)
	sd s6, 64(a0)
	sd s7, 72(a0)
	sd s8, 80(a0)
	sd s9, 88(a0)
	sd s10, 96(a0)
	sd s11, 104(a0)

	ld ra, 0(a1)
	ld sp, 8(a1)
	ld s0, 16(a1)
	ld s1, 24(a1)
	ld s2, 32(a1)
	ld s3, 40(a1)
	ld s4, 48(a1)
	ld s5, 56(a1)
	ld s6, 64(a1)
	ld s7, 72(a1)
	ld s8, 80(a1)
	ld s9, 88(a1)
	ld s10, 96(a1)
	ld s11, 104(a1)
	
	ret    /* return to ra */

然后为thread_create函数添加代码,为线程初始化上下文字段,最重要的两个寄存器是rasp,其中ra寄存器需要指向传进来的线程函数,在thread_switch函数中将被替换到CPU的ra,作为返回地址,即起到了一个跳板的作用,跳到了线程函数中;sp寄存器则需要指向线程的栈

void 
thread_create(void (*func)())
{
  struct thread *t;

  for (t = all_thread; t < all_thread + MAX_THREAD; t++) {
    if (t->state == FREE) break;
  }
  t->state = RUNNABLE;
  // YOUR CODE HERE
  t->context.ra = (uint64) func;
  t->context.sp = (uint64) (t->stack + STACK_SIZE);
}

thread_schedule函数中,增加一句代码调用thread_switch函数进行线程转换即可。

if (current_thread != next_thread) {         /* switch threads?  */
    next_thread->state = RUNNING;
    t = current_thread;
    current_thread = next_thread;
    /* YOUR CODE HERE
     * Invoke thread_switch to switch from t to next_thread:
     * thread_switch(??, ??);
     */
    thread_switch((uint64)&t->context, (uint64)&current_thread->context);
  }

Using threads

首先回答一个问题:
Q: 为什么两个线程都丢失了键,而不是一个线程?确定可能导致键丢失的具有2个线程的事件序列。
A: 当两个线程同时调用put且插入的哈希bucket是同一个时,涉及到链表插入的并发性问题,
其实在xv6-book中第六章有讲到过。由于这里是头插法,修改头指针指向当前新插入的节点时,
如果两个线程的操作交叉运行,则后运行的一个会被前运行的一个覆盖,使得插入的节点少了一个,
这种行为是不可预测的,所以两个线程都有可能丢失。

然后需要为代码加锁以修复并发put的问题,考虑如果两个线程并发put到两个不同的bucket中,不会引发问题,于是为每一个bucket设置一个锁即可。

pthread_mutex_t lock[NBUCKET];

然后在put函数中加上锁即可。

if(e){
    pthread_mutex_lock(&lock[i]);
    // update the existing key.
    e->value = value;
    pthread_mutex_unlock(&lock[i]);
} else {
    // the new is new.
    pthread_mutex_lock(&lock[i]);
    insert(key, value, &table[i], table[i]);
    pthread_mutex_unlock(&lock[i]);
}

Barrier

这一部分据文档描述就是加上一层屏障,进行线程同步,需要使用条件变量的知识,这里就不细说了,简单来说就是,让一些快的线程等一会,让最后一个到达的线程通知大家说可以继续走了,实现起来也很简单。文章来源地址https://www.toymoban.com/news/detail-406444.html

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 (bstate.nthread < nthread) {
    pthread_cond_wait(&bstate.barrier_cond, &bstate.barrier_mutex);
    pthread_mutex_unlock(&bstate.barrier_mutex);
    return;
  }
  bstate.nthread = 0;
  bstate.round ++;
  pthread_mutex_unlock(&bstate.barrier_mutex);
  pthread_cond_broadcast(&bstate.barrier_cond);
}

到了这里,关于【MIT 6.S081】Lab7: Multithreading的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MIT 6s081 lab1:Xv6 and Unix utilities

    作业网址:https://pdos.csail.mit.edu/6.828/2020/labs/util.html 下载,启动xv6系统 使用system call sleep .函数(在user/user.h中被声明)来完成 使用系统调用在一对管道上的两个进程之间“乒乓”一个字节,每个方向一个。父进程应该向子进程发送一个字节;子进程应打印“<pid>:received

    2024年01月17日
    浏览(37)
  • MIT 6.S081学习笔记(第〇章)

    本文涉及 xv6 《第零章 操作系统接口》相关,主要对涉及的进程、I/O、文件描述符、管道、文件等内容产生个人理解,不具有官方权威解释; 文章的目录与书中的目录没有严格的相关性; 文中会有问题 (Question) 字段,这来源于对 xv6 book 的扩展; 文中涉及的代码均能在macOS

    2024年02月09日
    浏览(49)
  • MIT6.S081学习笔记--lec 1

    abstract H/W 抽象化硬件 multiplex 多路复用 isolation 隔离性 sharing 共享(进程通信,数据共享) security / access control 安全性/权限控制 performance 性能/内核开销 range of applications 多应用场景 操作系统应该提供的功能:1. 多进程支持 2. 进程间隔离 3. 受控制的进程间通信 xv6 :一种在本

    2024年02月16日
    浏览(37)
  • MIT 6.S081 教材第八章内容 -- 文件系统 -- 02

    MIT 6.S081 2020 操作系统 本文为MIT 6.S081课程第八章教材内容翻译加整理。 本课程前置知识主要涉及: C语言(建议阅读C程序语言设计—第二版) RISC-V汇编 推荐阅读: 程序员的自我修养-装载,链接与库 术语inode(即索引结点)可以具有两种相关含义之一。它可能是指包含文件大小和

    2024年02月13日
    浏览(46)
  • 【MTI 6.S081 Lab】traps

    本实验阅读《深入理解计算机系统》第八章异常控制流并做shell实验将会是很有帮助的 本实验探讨了如何使用陷阱实现系统调用。您将首先使用堆栈进行热身练习,然后实现用户级陷阱处理的示例。 了解一下您在6.1910(6.004)中接触到的RISC-V程序集非常重要。在您的xv6 repo中

    2024年02月15日
    浏览(47)
  • MIT6.S081 - Lecture1: Introduction and Examples

    理解操作系统的设计和实现 通过 XV6 操作系统动手实验,可以扩展或改进操作系统 Abstraction: 对硬件进行抽象 Multiplex: 在多个应用程序之间共用硬件资源 Isolation: 隔离性,程序出现故障时,不同程序之间不能相互干扰 Sharing: 实现共享,如数据交互或协同完成任务 Securi

    2024年04月15日
    浏览(50)
  • MIT6.S081 - Lecture3: OS Organization and System Calls

    使用操作系统的主要原因是为了实现 CPU 多进程分时复用以及内存隔离 如果没有操作系统,应用程序会直接与硬件进行交互,这时应用程序会直接使用 CPU,比如假设只有一个 CPU 核,一个应用程序在这个 CPU 核上运行,但是同时其他程序也需要运行,因为没有操作系统来帮助

    2024年04月22日
    浏览(41)
  • MIT6.828/6.S081 Mac OS下搭建xv6和risc-v

    题外话: 其实我是一名非计算机专业的在校生,因为对软件开发和服务器开发很感兴趣,并且这方面的就业相对我来说资源比较充沛,所以就学习了mit6.828的实验 课程的学习直接跟着官网的schedule走就行,先看Lecture下提供的讲义和手册,然后完成相应的Lab,Lab共计10个,主要

    2024年03月09日
    浏览(38)
  • 6.s081/6.1810(Fall 2022)Lab2: System calls

    这个lab主要介绍了用户态到内核态的系统调用做了什么,并让我们照猫画虎完成了两个系统调用的实现。 环境搭建 Lab1: Utilities Lab2: System calls Lab3: Page tables Lab4: Traps Lab5: Copy-on-Write Fork for xv6 官网链接 xv6手册链接,这个挺重要的,建议做lab之前最好读一读。 xv6手册中文版,这

    2024年02月13日
    浏览(56)
  • mit 6.824 lab1分析

    略 map阶段每个worker应该把中间文件分成nReduce份,nReduce是reduce任务的数量 worker完成reduce任务后生成文件名 mr-out-X mr-out-X 文件每行应该是 \\\"%v %v\\\" 格式,参考 main/mrsequential.go worker处理完map任务,应该把生成的中间文件放到当前目录中,便于worker执行reduce任务时读取中间文件 当所

    2023年04月10日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包