在unix下创建进程无外乎 fork vfork clone 等方式。对于这几种方式的差异具体需要google。在这篇笔记中只记录在使用 vfork 过程中遇到的问题。
这样一段代码,编译执行结果令人疑惑:父子进程都在执行,子进程没有阻塞父进程的执行,一直到 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失败!(此处解释可能有些不正确,后续进一步学习后更正)
这样在子进程能执行到的地方加上 _exit(0); 其结果就是预期结果。
阅读(25) | 评论(0) | 转发(0) |
<script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/buttonLite.js#style=-1&uuid=&pophcol=3&lang=zh"></script> <script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/bshareC0.js"></script>
点击(此处)折叠或打开
- 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");
- }
相关热门文章
给主人留下些什么吧!~~
评论热议