示例代码中,父进程操作管道的写端,子进程操作管道的读端。如果现在想让父进程作为“读者”,代码应当如何修改?
fork()
后,case 0
和default
的部分相互调换位置就可以。这样父进程会关闭写并读取内容,子进程则会关闭读并发送内容。上面这种不同步修改 pp_ref 而导致的进程竞争问题在 user/fd.c 中的dup 函数中也存在。请结合代码模仿上述情景,分析一下我们的 dup 函数中为什么会出现预想之外的情况?
阅读上述材料并思考:为什么系统调用一定是原子操作呢?如果你觉得不是所有的系统调用都是原子操作,请给出反例。希望能结合相关代码进行分析。
.macro CLI
mfc0 t0, CP0_STATUS
li t1, (STATUS_CU0 | 0x1)
or t0, t1
xor t0, 0x1
mtc0 t0, CP0_STATUS
.endm
仔细阅读上面这段话,并思考下列问题
? 按照上述说法控制 pipeclose 中 fd 和 pipe unmap 的顺序,是否可以解决上述场景的进程竞争问题?给出你的分析过程。
? 我们只分析了 close 时的情形,那么对于 dup 中出现的情况又该如何解决?请模仿上述材料写写你的理解。
bss 在 ELF 中并不占空间,但 ELF 加载进内存后,bss 段的数据占据了空间,并且初始值都是 0。请回答你设计的函数是如何实现上面这点的?
为什么我们的 *.b 的 text 段偏移值都是一样的,为固定值?
在哪步,0 和 1 被"安排"为标准输入和标准输出?请分析代码执行流程,给出答案。
// user/init.c
close(0);
if ((r = opencons()) < 0)
user_panic("opencons: %e", r);
if (r != 0)
user_panic("first opencons used fd %d", r);
if ((r = dup(0, 1)) < 0)
user_panic("dup: %d", r);
// user/console.c
int
opencons(void)
{
int r;
struct Fd *fd;
if ((r = fd_alloc(&fd)) < 0)
return r;
if ((r = syscall_mem_alloc(0, (u_int)fd, PTE_V|PTE_R|PTE_LIBRARY)) < 0)
return r;
fd->fd_dev_id = devcons.dev_id;
fd->fd_omode = O_RDWR;
return fd2num(fd);
}
难点主要存在于把ELF文件装载入内存的操作。
用时基本与Lab5持平,低于Lab3、4.
迭代太可怕了。这次最终作业,成功地检验了自己一学期的成果。正如指导书的灵魂拷问:“你的大厦倒了吗?”(其实没有这么问)。
多少与这次测试点的设置有关,我测试点part1一直没有全部通过,仔细检查part1的代码并认定没有问题后,怀着悲伤——不,绝望,我开始了“重建大厦”的旅途。
但最后发现是part2的错误关联了part1……
当然,这也让我对迭代有了新的认知。
原文:https://www.cnblogs.com/Suxy-99/p/13178932.html