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之前是利用了管道的阻塞性质,子进程没写之前读的话会阻塞,能实现一样的效果。