在unix下创建进程无外乎 fork vfork clone 等方式。对于这几种方式的差异具体需要google。在这篇笔记中只记录在使用 vfork 过程中遇到的问题。
-
int main()
-
{
-
int pid;
-
if((pid=vfork()) == 0) {
-
printf("child %d\n", getpid());
-
} else if(pid > 0) {
-
printf("parent %d\n", getpid());
-
} else {
-
printf("error\n");
-
}
-
return 0;
-
}
这样一段代码,编译执行结果令人疑惑:父子进程都在执行,子进程没有阻塞父进程的执行,一直到 vfork 失败程序才结束。经过查询man手册,描述为 The vfork() function has the same effect as fork(2), except that the behavior is undefined if the process created by vfork() either modifies any data other than a variable of type pid_t used to store the return value from vfork(), or returns from the function in which vfork() was called, or calls any other function before successfully calling _exit(2) or one of the exec(3) family of functions.大概意思是子进程在成功调用_exit()或exec家族函数前 return了,其行为是未定义的。(网友告知,在子进程中没有调用_exit或exec直接return返回到了调用vfork的地方,所以导致程序一直在创建新的进程)
再回过头来分析下程序,vfork后,父子进程共享程序段(在exec前一直共享下去),当然包含vfork下面的所有执行语句,所以顺序执行打印,然后子进程return 0。此时,产生了未定义的行为。因为父子共享内存,子进程返回到vfork会影响父进程也返回到此处,这样每次父进程都创建一个新的子进程,而父进程始终存在,没有机会执行到return 0语句,导致程序一直执行下去直到vfork失败!(此处解释可能有些不正确,后续进一步学习后更正)
-
if((pid=vfork()) == 0) {
-
printf("child %d\n", getpid());
-
_exit(0);
-
} else if(pid > 0) {
-
printf("parent %d\n", getpid());
-
} else {
-
printf("error\n");
-
}
这样在子进程能执行到的地方加上 _exit(0); 其结果就是预期结果。
阅读(2061) | 评论(0) | 转发(0) |