chapter6练习
- 本节难度: 也就和lab3一样吧
编程作业
进程通信:邮件
这一章我们实现了基于 pipe 的进程间通信,但是看测例就知道了,管道不太自由,我们来实现一套乍一看更靠谱的通信 syscall吧!本节要求实现邮箱机制,以及对应的 syscall。
- 邮箱说明:每个进程拥有唯一一个邮箱,基于“数据报”收发字节信息,利用环形buffer存储,读写顺序为 FIFO,不记录来源进程。每次读写单位必须为一个报文,如果用于接收的缓冲区长度不够,舍弃超出的部分(截断报文)。为了简单,邮箱中最多拥有16条报文,每条报文最大长度256字节。当邮箱满时,发送邮件(也就是写邮箱会失败)。不考虑读写邮箱的权限,也就是所有进程都能够随意给其他进程的邮箱发报。
mailread:
syscall ID:401
C接口:
int mailread(void* buf, int len)
Rust接口:
fn mailread(buf: *mut u8, len: usize)
功能:读取一个报文,如果成功返回报文长度.
参数:
buf: 缓冲区头。
len:缓冲区长度。
说明:
len > 256 按 256 处理,len < 队首报文长度且不为0,则截断报文。
len = 0,则不进行读取,如果没有报文读取,返回-1,否则返回0,这是用来测试是否有报文可读。
可能的错误:
邮箱空。
buf 无效。
mailwrite:
syscall ID:402
C接口:
int mailwrite(int pid, void* buf, int len)
Rust接口:
fn mailwrite(pid: usize, buf: *mut u8, len: usize)
功能:向对应进程邮箱插入一条报文.
参数:
pid: 目标进程id。
buf: 缓冲区头。
len:缓冲区长度。
说明:
len > 256 按 256 处理,
len = 0,则不进行写入,如果邮箱满,返回-1,否则返回0,这是用来测试是否可以发报。
可以向自己的邮箱写入报文。
可能的错误:
邮箱满。
buf 无效。
实验要求
实现分支:ch6。
完成实验指导书中的内容,实现进程控制,可以基于 pipe 进行进程通信。
实现邮箱机制及系统调用,并通过 Rust测例 中 chapter6 对应的所有测例。
challenge: 支持多核。
实验检查
实验目录要求
目录要求不变(参考lab1目录或者示例代码目录结构)。同样在 os 目录下
make run
之后可以正确加载用户程序并执行。加载的用户测例位置:
../user/build/bin
。检查
可以正确
make run
执行,可以正确执行目标用户测例,并得到预期输出(详见测例注释)。
问答作业
举出使用 pipe 的一个实际应用的例子。
假设我们的邮箱现在有了更加强大的功能,容量大幅增加而且记录邮件来源,可以实现“回信”。考虑一个多核场景,有 m 个核为消费者,n 个为生产者,消费者通过邮箱向生产者提出订单,生产者通过邮箱回信给出产品。
假设你的邮箱实现没有使用锁等机制进行保护,在多核情景下可能会发生哪些问题?单核一定不会发生问题吗?为什么?
请结合你在课堂上学到的内容,描述读者写者问题的经典解决方案,必要时提供伪代码。
由于读写是基于报文的,不是随机读写,你有什么点子来优化邮箱的实现吗?
报告要求
简单总结本次实验与上个实验相比你增加的东西。(控制在5行以内,不要贴代码)
完成问答问题
(optional) 你对本次实验设计及难度的看法。