学习OS,它通常在任何教科书中看到,在父进程中使用fork()来创建子进程,有时在父进程中调用wait()来等待子进程的完成。
但是,如果我在孩子中使用wait()会发生什么?
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int
main(int argc, char** argv){
int x;
int w1, w2;
x = 100;
printf("the initialized x is: %d\n",x);
int rc = fork();
if(rc < 0){
fprintf(stderr, "fork failed.\n");
exit(1);
}
else if(rc == 0){
//x = 200;
w1 = wait(NULL);
printf("the x in child process (pid:%d) is: %d\n", (int) getpid(), x);
} else {
x = 300;
w2 = wait(NULL);
printf("the x in parent process (pid:%d) is: %d\n",(int) getpid(), x);
}
printf("the x in the end is: %d\n",x);
printf("the returns of waits: %d, %d\n",w1,w2);
return 0;
}
这段代码运行并显示以下内容:
dhcp175:hw_ch5 Suimaru$ ./a.out
the initialized x is: 100
the x in child process (pid:18844) is: 100
the x in the end is: 100
the returns of waits: -1, 0
the x in parent process (pid:18843) is: 300
the x in the end is: 300
the returns of waits: 0, 18844
如何解释?
答案 0 :(得分:2)
但是,如果我在孩子中使用wait()会发生什么?
您是否阅读过其文档?特别是关于返回值和错误条件的部分?我看到你做了一个很好的实验;在它和文档之间,应该已经很清楚,如果调用wait()
的进程没有要等待的子进程,那么它会立即返回-1
,表示错误。在这种情况下,errno
将设置为ECHILD
。
立即返回错误是完全合理的,对于唯一的另一种选择,如果调用进程没有子进程,则它等待,可能无限期地等待一个只要等待就不会发生的事件。
答案 1 :(得分:0)
您已经说明了示例输出中发生的情况,但为了获得更多详细信息,您必须在收到errno
系统调用中的失败代码后检查wait
值。虽然检查if (errno == ECHILD)
是有用的,并且可用于执行可能处理此错误的某些操作,但您还可以使用以下代码获取带有错误消息的字符串(字符数组):
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
...
char err_msg[4096]; // a buffer big enough to hold an error message
errno = 0; // clear errno just in case there was an earlier error
pid_t fpid = fork();
if (fpid < 0)
{
perror("fork failed.\n"); // prints out an error string based on errno
exit(1);
} else if (fpid == 0)
{ // in child
pid_t wpid = wait(NULL);
strerror_r(errno, err_msg, sizeof(err_msg)); // gets an error string
printf("child process (pid:%d), wpid:%d, %s\n", (int) getpid(), (int)wpid, err_msg);
} else {
int err_val;
wpid = wait(NULL);
err_val = errno;
errno = 0; // reset errno
strerror_r(err_val , err_msg, sizeof(err_msg)); // gets an error string
printf("parent process (pid:%d), wpid:%d, %s\n", (int) getpid(), (int)wpid, err_msg);
if (err_val != 0)
{
// there was an error, so what are you going to do about it?
}
}