Skip to content

Commit

Permalink
Update Chapter 1 Section 3
Browse files Browse the repository at this point in the history
  • Loading branch information
MeouSker77 authored and batkiz committed Feb 11, 2023
1 parent 2099371 commit 0ffc9ca
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 9 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

## 以下为英文原文地址

* [原文地址](https://pdos.csail.mit.edu/6.828/2018/xv6/book-rev11.pdf)
* [原文地址](https://pdos.csail.mit.edu/6.828/2022/xv6/book-riscv-rev3.pdf)

## 如何使用本仓库

Expand Down
15 changes: 7 additions & 8 deletions src/ch1.tex
Original file line number Diff line number Diff line change
Expand Up @@ -307,17 +307,17 @@ \section{管道}

这个程序调用了\texttt{pipe},这会创建一个新的管道,并把输入和输出文件描述符记录到数组\texttt{p}中。
\texttt{fork}之后,父进程和子进程都有指向管道的文件描述符。
子进程复制输入端到文件描述符0,然后关闭了\texttt{p}中的文件描述符,然后运行了\texttt{wc}。
子进程调用\texttt{close}和\texttt{dup}来确保文件描述符0指向管道的读取端,然后关闭\texttt{p}中的文件描述符,然后调用\texttt{exec}来运行\texttt{wc}。
\texttt{wc}从标准输入读取时,它实际上是从管道读取。
父进程关闭了管道的输入端,向管道写入数据,然后关闭了写入端。

如果没有数据可用,对管道的\texttt{read}调用会等待有数据被写入到管道或者所有指向管道输入端的文件描述符都已经被关闭;在后面这种情况下,\texttt{read}会返回0,就像是读取到普通文件的末尾一样。
\texttt{read}会阻塞直到有新的数据到达也是子进程运行\texttt{wc}之前先把管道的写入端关闭的一个原因:如果\texttt{wc}的一个文件描述符指向管道的写入端,那么\texttt{wc}将永远不会看到文件的结果
如果没有数据可用,对管道的\texttt{read}调用会等待有数据被写入到管道或者所有指向管道写入端的文件描述符都已经被关闭;在后面这种情况下,\texttt{read}会返回0,就像是读取到普通文件的末尾一样。
\texttt{read}会阻塞直到有新的数据到达也是子进程运行\texttt{wc}之前先把管道的写入端关闭的一个原因:如果\texttt{wc}的一个文件描述符指向管道的写入端,那么\texttt{wc}将永远不会看到文件结束符

xv6 shell以类似上面代码的方式实现了管道符(\texttt{|})例如\texttt{grep fork sh.c | wc -l}(8650)
xv6 shell以类似上面代码\href{https://github.com/mit-pdos/xv6-riscv/blob/riscv//user/sh.c#L101}{(user/sh.c:101)}的方式实现了管道符(\texttt{|})例如\texttt{grep fork sh.c | wc -l}。
子进程首先创建一个管道来连接管道符的左侧和右侧。
然后它为左侧和右侧分别调用\texttt{fork}和\texttt{runcmd},然后等待两侧都结束。
管道符的右侧可能是一个包含管道的命令(例如,\texttt{a | b | c},这时它自己还会fork两个新的子进程(一个运行\texttt{b},一个运行\texttt{c})。
然后它为左侧和右侧都调用\texttt{fork}和\texttt{runcmd},然后等待两侧都结束。
管道符的右侧可能是一个包含管道的命令(例如,\texttt{a | b | c},这时它自己还会fork两个新的子进程(一个运行\texttt{b},一个运行\texttt{c})。
因此,shell可能会创建一棵子进程树。
树的叶节点就是命令,内部的节点是等待左侧和右侧的子进程都执行结束的进程。
理论上讲,你可以让内部的节点运行管道符左侧的命令,但正确的实现这样的逻辑会让实现更加复杂。
Expand All @@ -334,8 +334,7 @@ \section{管道}
在这种情况下,管道相比临时文件至少有4个优势。
第一,管道会自动清理自己;而使用文件重定向,shell需要在结束之后谨慎地删除\texttt{/tmp/xyz}。
第二,管道可以传输任意长的数据流,而文件重定向需要磁盘上有足够大的空闲空间来存储所有的数据。
第三,管道运行不同阶段并行执行,而文件的方法需要第一个程序结束之后才能运行第二个。
第四,如果你在实现进程间通信,管道的阻塞读取和写入比文件的非阻塞语言更加高效。
第三,管道允许不同阶段并行执行,而文件的方法需要第一个程序结束之后才能运行第二个。

\section{文件系统}
xv6文件系统提供数据文件,它们是未解析的字节数组;以及目录,包含指向数据文件和其他目录的名称。
Expand Down

0 comments on commit 0ffc9ca

Please sign in to comment.