本帖最后由 yuanlai2010 于 2014-8-7 10:57 编辑
进程等待与终止
参与Helper2416开发板助学计划心得
进程等待
在上一张帖子中的第一个实验中,出现了如下的打印结果,有点乱.
- [root@jyxtec fork]# ./fork_arm
- fork program starting!
- this is parant, the PID is 126
- and the count = 1
- [root@jyxtec fork]# this is child, the PID is 127
- and the count = 1
复制代码分析可以知道,父进程肯定是在子进程结束之间就已经结束了,这里也可以看出,子进程有它自己的生命周期,且可以独立运行的。
可以通过在父进程中调用wait函数来等待子进程结束。
- #include <sys/types.h>
- #include <sys/wait.h>
- pid_t wait(int *stat_loc):
复制代码一旦调用wait,父进程将会进入阻塞状态直到子进程的状态信息出现为止,这将在子进程结束时发出这个状态信息。这个调用返回子进程的PID,他通常是已经结束运行的子进程的PID。状态信息允许父进程了解子进程的退出状态,即子进程的main函数返回的值或者子进程中exit函数的退出码。如果stat_loc不是空指针,状态信息将被写入他所指向的位置。
代码实例
- /* 2014 - 08 -07
- * yuanlai2010
- * fork调用测试
- */
-
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <stdio.h>
- #include <stdlib.h>
-
- int main()
- {
- pid_t pid;
- int count = 0;
-
- printf("fork program starting!\n");
-
- pid = fork();
-
- switch(pid){
- case -1:
- printf("fork failed\n");
- exit(1);
- case 0:
- printf("this is child, the PID is %d\n", getpid());
- printf("and the count = %d\n",++count);
- break;
- default:
- printf("this is parant, the PID is %d\n",getpid());
- printf("and the count = %d\n",++count);
- wait(NULL);
- break;
- }
- exit(0);
- }
复制代码运行结果
- [root@jyxtec fork]# ./fork_arm
- fork program starting!
- this is parant, the PID is 128
- and the count = 1
- this is child, the PID is 129
- and the count = 1
- [root@jyxtec fork]#
复制代码加入wait后可以看到显示的信息正常了,但这并不是wait真正要完成的工作,接下来继续来探讨
.
进程终止
子进程终止时,它与父进程之间的关联还会继续保持,直到父进程也终止或者父进程调用wait或者waitpid才算真正的结束,因为子进程在终止后到正真结束之前,虽然子进程不再运行了,但它却还存在与系统中,因为它的退出码还需要保存起来,以备父进程的wait调用使用。这时他将成为一个僵尸进程(zombie)有些Linux分支中可能称为(defunct)。
但是,如果在父进程结束后,子进程还在运行;又或者说子进程先终止了,但是父进程一直没有调用wait或者waitpid,那么也只能等待父进程结束,然后子进程再自动把PID为1的进程(init)作为自己的父进程。这些子进程(僵尸进程)在被init发现后,便调用wait来释放他们。不过在这之前这些zombie一直占用着系统资源,所以编写程序的时候,注意在调用fork创建新的进程之后一定记得调用wait或者waitpid释放子进程占用的系统资源。
在上面的叙述中还提到了waitpid,它是另一个系统调用可以用来等待子进程的结束,可以用它来等待某个特定的进程结束、
- #include <sys/types.h>
- #include <sys/wait.h>
- pid_t waitpid(pid_t pid, int *stat_loc, int options);
复制代码pid参数指定需要等待的子进程的PID,如果它的值为-1,waitpid将返回任一子进程的信息。与wait一样,如果stat_loc不是空指针,waitpid将把状态信息写到他所指向的位置。Option参数可用来改变waitpid行为,其中最有用的一个选项是WNOHANG,他的作用就是让父进程去检测有没有子进程结束,但是并不将自己挂起,如果有的话释放子进程的资源,可没有的话就继续运行咯。
所以比较实用的一种调用方法如下:
- waitpid(child_pid,(int *)0, WNOHANG);
复制代码用来周期性的检测特定的子进程是否结束,如果子进程没有结束或者意外终止,它就返回0,否侧返回child_pid。如果waitpid失败,将返回-1,并设置errno。
这样对比起来,waitpid的使用还是相当灵活的。
论坛ID:yuanlai2010
发表时间:2014-08-07