本文会将lab1中的思路以及知识点进行分析,并作为作者学习MIT 6.828的一个学习总结,希望能够帮助到学习该lab的同学们
中文版书籍:中文版书籍
实验教案地址:教案地址
操作系统接口
在操作系统中,为了能够有效地与操作系统内核进行交互,所以衍生出操作系统接口,能够为用户提供服务。
常见地一些系统调用地接口如下所示:
进程,
XV6操作系统中进程由两个部分组成:用户的内存空间与进程状态,xv6能够分时的方法去切换进程通过对寄存器进行保存的处理
xv6 通常隐式地分配用户的内存空间。fork 在子进程需要装入父进程的内存拷贝时分配空间,exec 在需要装入可执行文件时分配空间。一个进程在需要额外内存时可以通过调用 sbrk(n) 来增加 n 字节的数据内存。 sbrk 返回新的内存的地址。
IO与文件描述符
文件描述符是一个整数,它代表了一个进程可以读写的被内核管理的对象。进程可以通过多种方式获得一个文件描述符,如打开文件、目录、设备,或者创建一个管道(pipe),或者复制已经存在的文件描述符。
每个进程都有一张表,而 xv6 内核就以文件描述符作为这张表的索引,所以每个进程都有一个从0开始的文件描述符空间。
最常见的文件描述符:0 输入流 1 输出流 2 错误流
dup pipe的使用
(209条消息) xv6中pipe&dup_xv6 dup函数的含义_G129558的博客-CSDN博客
lab1
实验目标:熟悉常见的系统调用
stat fork dup pipe read write open等
sleep
为xv6实现UNIX程序睡眠;您的睡眠应该在用户指定的时间内暂停。tick是由xv6内核定义的时间概念,即来自计时器芯片的两次中断之间的时间。
具体代码如下所示:
./grade-lab-util sleep
"include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int main(int argc, char *argv[]){
if(argc <= 2) sleep(atoi(argv[l]));return o;
知识点: 通过atoi 实现字符串与数字之间的转化
pingpong
通过fork与pipe实现两个进程之间的通信
#include "kernel/types.h"
#include "user/user.h"
int main(int argc, char *argv[J) {
int parent_fd[2], child_fd[2];
pipe(parent_fd);
pipe(child_fd);
char buf[64];
if (fork()){
// Parent
close(child_fd[l]);
write(parent_fd[ij,"ping", strlen("ping"));
read(child_fd[o], buf, 4);
printf("%d:received %s\n", getpid(), buf);
close(parent_fd[1]);
close(parent_fd[0]);
close(child_fd[o]);
} else {
// Child
close(parent_fd[1]);
read(parent_fd[o], buf, 4);
printf("%d:-received %s\n", getpid(), buf);
write(child_fd[i],"pong", strlen("pong"));
close(child_fd[l]);
close(child_fd[o]);
exit(0);
知识点:
- fork() 在进行创建子进程时会将所有的数据以及file table进行复制,随后依次执行,在子进程中fork()返回0副进程中返回对应的PID
- getpid()能够得到该进程下的PID号
- 在进行发送时需要考虑顺序关系,也可以通过wait进行等待
primes
思路:首先将所有的数字放入pipe的输入流,随后在输出流一端就行读取,然后再通过fork()创建进程,在主进程中将处理后的数据进行发送,副进程中进行接受,依次往复
我们可以通过如下代码进行实现:
find
思路:在实现find中,通过学习ls.c中的如何解析文件状态,fstat结构体如下
通过判断文件的类型,将T_DIR文件类型的文件中,对所有的文件进行遍历,其中遍历的操作如下所示:
关键代码如下所示:
xargs
xargs通过等待输入流的数据到来,随后将数据作为参数添加到该命令的后边即可