国内的OS课程可能只是在表面上教你操作系统的概念,像是在玩一场模拟器游戏,只是看看别人玩的样子,终究还是在OS的世界里迷失了方向。
Implement the UNIX program sleep for xv6; your sleep should pause for a user-specified number of ticks. A tick is a notion of time defined by the xv6 kernel, namely the time between two interrupts from the timer chip. Your solution should be in the file user/sleep.c.
Some hints:
Before you start coding, read Chapter 1 of the xv6 book.
(1.先看书捏)
Look at some of the other programs in user/ (e.g., user/echo.c, user/grep.c, and user/rm.c) to see how you can obtain the command-line arguments passed to a program.
(2.看上面几个文件来你如何获取命令行参数)
If the user forgets to pass an argument, sleep should print an error message.
(3.没传参需要特殊处理)
The command-line argument is passed as a string; you can convert it to an integer using atoi (see user/ulib.c).
(4.命令行输入的参数都是字符串,sleep需要的数字需要用atoi转化成整数)
Use the system call sleep.
(5.使用写好的sleep系统调用)
See kernel/sysproc.c for the xv6 kernel code that implements the sleep system call (look for sys_sleep), user/user.h for the C definition of sleep callable from a user program, and user/usys.S for the assembler code that jumps from user code into the kernel for sleep.
()
Make sure main calls exit() in order to exit your program.
(确保程序最后用系统调用exit()退出)
Add your sleep program to UPROGS in Makefile; once you've done that, make qemu will compile your program and you'll be able to run it from the xv6 shell.
(MakeFile文件里要把sleep加上,这部分我参考的别人的MakeFile)
Look at Kernighan and Ritchie's book The C programming language (second edition) (K&R) to learn about C.
(C基础薄弱的可以看这本书)
///user/echo.c
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int
main(int argc, char *argv[])
{
int i;
for(i = 1; i < argc; i++){
write(1, argv[i], strlen(argv[i]));
if(i + 1 < argc){
write(1, " ", 1);
} else {
write(1, "\n", 1);
}
}
exit(0);
}
//user/grep.c
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int
main(int argc, char *argv[])
{
int fd, i;
char *pattern;
if(argc <= 1){
fprintf(2, "usage: grep pattern [file ...]\n");
exit(1);
}
pattern = argv[1];
if(argc <= 2){
grep(pattern, 0);
exit(0);
}
for(i = 2; i < argc; i++){
if((fd = open(argv[i], 0)) < 0){
printf("grep: cannot open %s\n", argv[i]);
exit(1);
}
grep(pattern, fd);
close(fd);
}
exit(0);
}
//user/rm.c
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int
main(int argc, char *argv[])
{
int i;
if(argc < 2){
fprintf(2, "Usage: rm files...\n");
exit(1);
}
for(i = 1; i < argc; i++){
if(unlink(argv[i]) < 0){
fprintf(2, "rm: %s failed to delete\n", argv[i]);
break;
}
}
exit(0);
}
参考一下上面的三个.c文件,很明显看出:
1.argc是参数个数,agrv是个二维字符数组,argv[0]是第一个参数,argv[1]是第二个参数, 那么对于我们要实现的sleep,输入sleep xxx,则sleep是作为argv[0],xxx作为argv[1]。
2.没传sleep需要的参数,需要特判。
3.若有参数,则用atoi把字符串转化成整数,最后调用系统调用sleep
以下是我实现的sleep.c,已通测试
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int main(int argc,char *argv[]){
int time;
if(argc < 2){
printf("You forget to pass an argument, so I print an error message.");
exit(1);
}
time = atoi(argv[1]);
sleep(time);
exit(0);
}
Write a program that uses UNIX system calls to ''ping-pong'' a byte between two processes over a pair of pipes, one for each direction. The parent should send a byte to the child; the child should print "
Some hints:
Use pipe to create a pipe.
(使用pipe系统调用来创建管道,这个博主讲的很好,易于理解linux管道pipe详解_linux pipe-CSDN博客)
Use fork to create a child.
(使用fork创建子进程,父子通信嘛)
Use read to read from the pipe, and write to write to the pipe.
(使用read系统调用来从管道读写)
Use getpid to find the process ID of the calling process.
(使用getpid调用获得当前进程id,answer要输出)
Add the program to UPROGS in Makefile.
User programs on xv6 have a limited set of library functions available to them. You can see the list in user/user.h; the source (other than for system calls) is in user/ulib.c, user/printf.c, and user/umalloc.c.
(用user.h下提供的调用)
Run the program from the xv6 shell and it should produce the following output:
$ make qemu
...
init: starting sh
$ pingpong
4: received ping
3: received pong
$
我的代码如下,已满分:
(想了大半天,知道用两个管道那就很容易了,一锤定easy)
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int main(int argc,char * argv[]){
int p[2];
int p2[2];
char buf[1024];
pipe(p);
pipe(p2);
char *a = "hello mychild";
char *b = "hello myparent";
if(fork() == 0){
close(p[1]);
int len = read(p[0],buf,sizeof(buf));
if(len > 0)
printf("%d: received ping\n",getpid());
close(p[0]);
close(p2[0]);
write(p2[1],b,strlen(b));
close(p2[1]);
}else{
close(p[0]);
write(p[1],a,strlen(a));
wait((int*)0);
int len = read(p2[0],buf,sizeof(buf));
if(len > 0)
printf("%d: received pong\n",getpid());
close(p[0]);
close(p[1]);
close(p2[0]);
close(p2[1]);
}
exit(0);
}
最近主要在忙别的,后面的题也会好好做,慢慢更~