8.1.4 等待进程结束

来源:互联网 发布:网络启动设置 编辑:程序博客网 时间:2024/06/16 14:11

8.1.4  等待进程结束

子进程虽然是独立于父进程的,但是和父进程之间是有之间关系的。子进程从属于父进程,整个系统的进程是一个倒过来的树形结构,所有的进程都是从init进程创建来的。当进程结束的时候它的父进程会收回子进程的资源。这时会产生一个问题,当父进程创建子进程以后,两个进程是无序运行的。如果父进程先于子进程结束,那么子进程就会因为找不到父进程的进程号而无法通知父进程,导致资源无法释放。因此,需要一种方法让父进程知道子进程在什么时候结束。

Linux系统提供给了一个waitpid()函数,它的作用是等待另外一个进程结束,函数定义如下:

 

#include <sys/types.h>

#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *status, int options);

 

8-2展示了参数pid指定等待子进程的几种方式。

8-2  waitpid()函数的pid参数及意义

pid取值

   

<–1

等待所有其进程组标识等于pid绝对值的子进程

–1

等待任何子进程

0

等待任何其组标识等于调用进程组标识的进程

>0

等待其进程标识等于pid的进程

 

参数pid不同的取值指定了父进程等待子进程状态的不同方式,在实际使用中可根据需要选择一种方式。参数status指向子进程的返回状态,可通过表8-3列出的宏查询。

8-3  获取waitpid()函数的status参数值的宏及作用

   

   

WIFEXITED(status)

如果子进程正常终止,则返回真。例如:通过调用exit()_exit(),或者从main()return语句返回

WEXITSTATUS(status)

返回子进程的退出状态。这是来自子进程调用exit()_exit()时指定的参数,或者来自main内部return语句参数的最低字节。只有WIFEXITED返回真时,才应该使用

WIFSIGNALED(status)

如果子进程由信号所终止则返回真

WTERMSIG(status)

返回导致子进程终止的信号数量。只有WIFSIGNALED则返回真时,才应该使用

WCOREDUMP(status)

如果子进程导致内核转存返回真。只有WIFSIGNALED返回真时,才应该使用。并非所有平台都支持这个宏,使用时应放在#ifdef WCOREDUMP ... #endif内部

WIFSTOPPED(status)

如果信号导致子进程停止执行则返回真

WSTOPSIG(status)

返回导致子进程停止执行的信号数量。只有WIFSTOPPED返回真时,才应该使用

WIFCONTINUED(status)

如果信号导致子进程继续执行则返回真

在程序中可以通过表8-3的宏来查询status代表的返回状态。

参数options可以是0个或表8-4所示的参数取值通过或运算的组合值。

8-4  waitpid()函数的options参数取值及解释

options取值

   

WNOHANG

如果没有子进程退出,立即返回

WUNTRACED

如果有处于停止状态的进程将导致调用返回

WCONTINUED

如果停止了的进程由于SIGCONT信号的到来而继续运行,调用将返回

 

通常我们在程序中使用0,用户可根据需要指定表8-4中的options值。

实例8-3  在父进程中使用waitpid ()函数等待指定进程号的子进程返回

 

1 #include <sys/types.h>

2 #include <unistd.h>

3 #include <stdio.h>

4 #include <stdlib.h>

5

6 int main()

7 {

8   pid_t pid, pid_wait;

9   int status;

10

11   pid = fork();                          // 创建子进程

12   if (-1==pid) {                         // 检查是否创建成功

13     printf("Error to create new process!/n");

14     return 0;

15   }

16   else if (pid==0) {                     // 子进程

17     printf("Child process!/n");

18   } else {                               // 父进程

19     printf("Parent process! Child process ID: %d/n", pid);

20     pid_wait = waitpid(pid, &status, 0);      // 等待指定进程号的子进程

21     printf("Child process %d returned!/n", pid_wait);

22   }

23

24   return 0;

25 }

26

 

程序第20行,在父进程中使用waitpid()函数等待变量pid指定的子进程返回,并且把子进程状态写入status变量中。这里由于程序很简单,不涉及复杂的操作,所以并不判断status的值。最后父进程在21行打印出了返回的子进程的进程号。程序运行结果如下:

 

Child process!

Parent process! Child process ID: 4116

Child process 4116 returned!

 

从程序运行结果可以看出,父进程创建进程号为4116的子进程成功,并且使用waitpid()函数等到了子进程结束。

 

原创粉丝点击