MIT6.S081 学习——xv6系统调用函数的使用
| 函数类型 | 函数名称 | 函数参数 | 函数作用及返回值 |
|---|---|---|---|
| int | fork() | 无 | ① |
| int | exit() | int status | ② |
| int | wait() | int *status | ③ |
| int | exec() | char *file, char *argv[] | ④ |
①创建一个进程,并且返回子进程的PID。
例如:
int pid;
pid = fork();
这里fork()函数创建了一个新进程被称为子进程,其内存内容与调用的进程完全相同,原进程被称为父进程。
并且在父进程和子进程中,fork都会返回。在父进程中,fork返回子进程的PID;在子进程中,fork返回0。
ps:
Unix并没有一个直接的方法让子进程等待父进程。wait系统调用只能等待当前进程的子进程。所以wait的工作原理是,如果当
前进程有任何子进程,并且其中一个已经退出了,那么wait会返回。但是如果当前进程没有任何子进程,比如在这个简单的例子
中,如果子进程调用了wait,因为子进程自己没有子进程了,所以wait会立即返回-1,表明出现错误了,当前的进程并没有任何子进程。
简单来说,不可能让子进程等待父进程退出。
②终止当前进程,并将status传递给wait()。不会返回。
exit系统调用会使得调用它的进程退出,并释放资源,例如内存和打开的文件。在Unix中,如果一个程序成功退出那么会
将退出状态码设置为0,如果退出失败或者出现其他异常情况,可以将异常状态码设置为非0,用以指示错误或者错误类型。
③等待子进程结束,并将status接收到参数*status中,返回其PID。
例如:
int pid,status;
pid = fork();
if(0 == pid)
{
char *argv[] = {"hello", "hello","world",0};
exec("hello"argv);
printf("exec failed!\n");
exit(1);
}
else
{
printf("parent waiting\n");
wait(&status);
printf("the child exited with status %d\n",status);
exit(0);
}
首先创建了一个子进程,判断是子进程还是父进程。如果exec()函数运行出现错误那么向下运行将错误状态码传递给wait()。
如此,父进程可以读取wait的参数,并决定子进程是否成功的完成了。
wait系统调用返回当前进程的一个已退出(或被杀死)的子进程的PID,并将该子进程的退出状态码复制到一个地址,该地址由wait参数提供;
如果调用者的子进程都没有退出,则wait等待一个子进程退出。如果调用者没有子进程,wait立即返回-1。如果父进程不关心子进程的退出状态,
可以传递一个0地址给wait。
④通过给定参数加载并执行一个文件;只在错误时返回。
exec系统调用使用新内存映像来替换进程的内存, 新内存映像从文件系统中的文件中进行读取。这个文件必须有特定的格式,它指定了文件中
哪部分存放指令,哪部分是数据,在哪条指令开始,等等。当exec成功时,它并不返回到调用程序。
exec需要两个参数:包含可执行文件的文件名和一个字符串参数数组。
例如:
char* *argv[3];
argv[0] = "echo";
argv[1] = "hello";
argv[2] = 0;
exec("/bin/echo", argv);
printf("exec error\n");
上述代码会执行/bin/echo程序,并将argv数组作为参数。大多数程序都会忽略参数数组的第一个元素,也就是程序名称。

浙公网安备 33010602011771号