【MIT 6.S081】2020, 实验记录(7),Lab: Multithreading

2024-03-13 21:44

本文主要是介绍【MIT 6.S081】2020, 实验记录(7),Lab: Multithreading,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

    • Task 1: Uthread: switching between threads
    • Task 2:Using threads
    • Task 3:Barrier

Task 1: Uthread: switching between threads

这个实验是要求实现用户级线程的创建和调度,有点类似于有栈协程。非常有意思,值得多学习。

在完成这个实验前,需要了解 XV6 如何实现的进程的调度,然后通过在模拟进程切换的逻辑实现用户级线程的创建和切换。

在 kernel 调度进程时,会使用 context 来保存被挂起的进程的寄存器上下文,我们这里也需要一个类似的结构体来保存这些上下文(在 uthread.c 中声明):

// 模仿 kernel/proc.h 中的 struct context
// 保存用户线程的上下文
struct thread_context {uint64 ra;uint64 sp;// callee-saveduint64 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 中:

thread_context
thread_create() 中初始化这个字段,让其中的 ra 字段指向线程需要执行的函数(因为线程切换后会执行 ra 寄存器所指向的位置),让其中的栈指针指向合适的位置:

thread-create

然后模仿 kernel 中用来切换进程的 swtch 函数,实现线程切换时上下文的切换(也就是保存现有的各个寄存器值到 context 中,把新线程的 context 中保存的各个寄存器的值写入寄存器中),函数 thread_switch() 已经声明在了 uthread.c 中,但这部分的实现需要我们模仿 kernel/swtch.S 使用汇编语言实现在 uthread_switch.S 中:

uthread_switch.S
这个最后的 ret 会回到 ra 寄存器所指向的位置,也就是我们想让这个线程所执行的函数。

最后在线程调度的函数中加入 thread_switch() 的调用,参数就是现在线程和新线程的 context 指针:

在这里插入图片描述
至此,第一个 task 就完成了。

Task 2:Using threads

这个 task 就不是在 xv6 中写代码了,而是使用 Unix 提供的 pthread 及相关工具来实现一个并发安全的 hash map。

最简单的思路就是有一个 lock,每一次对 hash map 的读写都需要先获取这个 lock 再操作。但是这会存在效率问题,因为一个 map 有很多 buckets,而大多数情况下两个线程同时写 hash map 时涉及的 buckets 并没有关联。为了解决这个问题,可以让每个 bucket 都关联一个 lock,需要访问一个 bucket 时就需要先获取这个 bucket 所关联的 lock。

首先声明 locks,锁的数量与 bucket 的数量相同:

locks 声明

然后初始化 locks:

初始化 locks

然后在 hash map 的 get 和 put 函数操作内加锁。

get 函数中,首先计算出在 entry 哪个 bucket 中,然后对这个 bucket 相关联的 lock 上锁,操作完成后再解锁:

get 操作

put 函数也是类似:

put 函数

上面完成后,这个 task 就通过了:

task 2

Task 3:Barrier

最后一个 task 的难度也不大,主要考察 pthread 中条件变量的使用,task 是实现 barrier() 函数,一共有 n 个进程,每个进程调用了 barrier() 后会等待,直到所有 n 个进程都调用了 barrier() 后才能继续进行下去。

实现难度不大,利用好 mutex 和 cond 就行:

barrier
实现好这个函数后,就可以通过测试了。

task 3

这篇关于【MIT 6.S081】2020, 实验记录(7),Lab: Multithreading的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

Spring Boot中定时任务Cron表达式的终极指南最佳实践记录

《SpringBoot中定时任务Cron表达式的终极指南最佳实践记录》本文详细介绍了SpringBoot中定时任务的实现方法,特别是Cron表达式的使用技巧和高级用法,从基础语法到复杂场景,从快速启... 目录一、Cron表达式基础1.1 Cron表达式结构1.2 核心语法规则二、Spring Boot中定

国内环境搭建私有知识问答库踩坑记录(ollama+deepseek+ragflow)

《国内环境搭建私有知识问答库踩坑记录(ollama+deepseek+ragflow)》本文给大家利用deepseek模型搭建私有知识问答库的详细步骤和遇到的问题及解决办法,感兴趣的朋友一起看看吧... 目录1. 第1步大家在安装完ollama后,需要到系统环境变量中添加两个变量2. 第3步 “在cmd中

Spring Retry 实现乐观锁重试实践记录

《SpringRetry实现乐观锁重试实践记录》本文介绍了在秒杀商品SKU表中使用乐观锁和MybatisPlus配置乐观锁的方法,并分析了测试环境和生产环境的隔离级别对乐观锁的影响,通过简单验证,... 目录一、场景分析 二、简单验证 2.1、可重复读 2.2、读已提交 三、最佳实践 3.1、配置重试模板

在 Spring Boot 中使用异步线程时的 HttpServletRequest 复用问题记录

《在SpringBoot中使用异步线程时的HttpServletRequest复用问题记录》文章讨论了在SpringBoot中使用异步线程时,由于HttpServletRequest复用导致... 目录一、问题描述:异步线程操作导致请求复用时 Cookie 解析失败1. 场景背景2. 问题根源二、问题详细分

关于Spring @Bean 相同加载顺序不同结果不同的问题记录

《关于Spring@Bean相同加载顺序不同结果不同的问题记录》本文主要探讨了在Spring5.1.3.RELEASE版本下,当有两个全注解类定义相同类型的Bean时,由于加载顺序不同,最终生成的... 目录问题说明测试输出1测试输出2@Bean注解的BeanDefiChina编程nition加入时机总结问题说明