uCore-Tutorial-Guide-2023S/source/chapter5/3exercise.rst

92 lines
3.6 KiB
ReStructuredText
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

chapter5练习
==============================================
- 本节难度: **看似唬人,其实就那样**
本章任务
----------------------------------------
- ``make test BASE=1`` 执行 usershell然后运行 ``ch5b_usertest``
- merge ch4 的修改,运行 ``ch5_mergetest`` 检查 merge 是否正确。
- 结合文档和代码理解 fork, exec, wait 的逻辑。结合课堂内容回答本章问答问题(注意第二问为选做)。
- 完成本章变成作业。
- 最终,完成实验报告并 push 你的 ch5 分支到远程仓库。
编程作业
---------------------------------------------
进程创建
+++++++++++++++++++++++++++++++++++++++++++++
大家一定好奇过为啥进程创建要用 fork + execve 这么一个奇怪的系统调用,就不能直接搞一个新进程吗?思而不学则殆,我们就来试一试!这章的编程练习请大家实现一个完全 DIY 的系统调用 spawn用以创建一个新进程。
spawn 系统调用定义( `标准spawn看这里 <https://man7.org/linux/man-pages/man3/posix_spawn.3.html>`_ )
- syscall ID: 400
- C 接口: ``int spawn(char *filename)``
- 功能:相当于 fork + exec新建子进程并执行目标程序。
- 说明成功返回子进程id否则返回 -1。
- 可能的错误:
- 无效的文件名。
- 进程池满/内存不足等资源错误。
实现完成之后,你应该能通过 ch5_spawn* 对应的所有测例,在 shell 中执行 ch5_usertest 来执行所有测试。
tips:
- 注意 fork 的执行流,新进程 context 的 ra 和 sp 与父进程不同。所以你不能在内核中通过 fork 和 exec 的简单组合实现 spawn。
- 在 spawn 中不应该有任何形式的内存拷贝。
问答作业
--------------------------------------------
1. fork + exec 的一个比较大的问题是 fork 之后的内存页/文件等资源完全没有使用就废弃了,针对这一点,有什么改进策略?
2. [选做,不占分] 其实使用了题(1)的策略之后fork + exec 所带来的无效资源的问题已经基本被解决了,但是今年来 fork 还是在被不断的批判,那么到底是什么正在"杀死"fork回答合理即可。可以参考 `fork-hotos19 <https://www.microsoft.com/en-us/research/uploads/prod/2019/04/fork-hotos19.pdf>`_
3. 请阅读代码并分析如下程序的输出,不考虑运行错误,不考虑行缓冲,不考虑中断:
.. code-block:: c
int main(){
int val = 2;
printf("%d", 0);
int pid = fork();
if (pid == 0) {
val++;
printf("%d", val);
} else {
val--;
printf("%d", val);
wait(NULL);
}
val++;
printf("%d", val);
return 0;
}
如果 fork() 之后一定主程序先运行结果如何?如果 fork() 之后一定 child 先运行结果如何?
4. 请分析如下程序运行后最终输出 `A` 的数量(已知 ``&&`` 的优先级比 ``||`` 高)
.. code-block:: c
int main() {
fork() && fork() && fork() || fork() && fork() || fork() && fork();
printf("A");
return 0'
}
[选做,不占分] 更进一步,如果给出一个 ``&&`` ``||`` 的序列,你如何设计一个程序来得到答案?
报告要求
---------------------------------------
注意目录要求,报告命名 ``lab3.pdf``,位于 ``reports`` 目录下。 后续实验同理。
- 注明姓名学号。
- 完成 ch5 问答作业。
- [可选,不占分]你对本次实验设计及难度的看法。