2.Lab One —— Util
sleep
运行效果
$ make qemu
...
init: starting sh
$ sleep 10
(nothing happens for a little while)
$
1.在Makefile中添加指令 $U/_sleep\,确保构建过程生成 _sleep 目标文件
2.创建user/sleep.c并编写,事实上就是调用了系统调用sleep
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"int main(int argc ,char* argv[]){int n;if(argc != 2){fprintf(2,"Please enter a number\n");exit(1);}else{n = atoi(argv[1]); //atoi将字符串转变为数字//连接测试。。。sleep(n);exit(0);}
}
pingpong
运行效果
$ make qemu
...
init: starting sh
$ pingpong
4: received ping
3: received pong
$
1.在Makefile中添加指令 $U/_pingpong\,确保构建过程生成 _pingpong 目标文件
2.创建user/pingpong.c并编写,思路就是创建两个管道,fork一个子进程出来,一个管道给父进程,一个管道给子进程
不过如果管道的写端没有close的情况下,再管道中数据为空时对管道的读取会阻塞,因此不需要的管道描述符应该尽早关闭
#include "kernel/types.h"
#include "user/user.h"int main(int argc,char const *argv[]){int p1[2],p2[2]; //创建一个管道pipe(p1);pipe(p2);//创建管道,得到一个长度为2的数组//p1[0]表示读端,p1[1]表示写端int pid = fork(); //创建一个子进程if(pid == 0){ //子进程char buf;read(p1[0],&buf,1); //子进程读取一个字符printf("%d: received ping\n",getpid());write(p2[1],&buf,1); //子进程写入一个字符}else{ //父进程write(p1[1],"1",1); //父进程写入一个字符char buf;read(p2[0],&buf,1); //父进程读取一个字符printf("%d: received pong\n",getpid());wait(0); //等待子进程结束}exit(0);}
事实上,进到子进程里面可以把用不到的p1写和p2读关闭,即close(p1[1])和close(p2[0])
同理父进程也是一样,同时我这里wait放在最后并没有选择放在父进程read之前是利用了管道的阻塞性质,子进程没写之前读的话会阻塞,能实现一样的效果。
