问题
在创建进程这一节内容中,我们看到,消息的输出是父子进程交替输出,且父进程在子进程之前结束。如果要安排父进程在子进程结束之后才结束。可以调用wait函数。
函数说明
pid_t wait( int * stat_loc );
包含的头文件: #include <sys/types.h>
#include <sys/wait.h>
返回值:子进程的PID
参数:如果stat_loc不是一个空指针,状态信息将被写入它指向的位置
sys/wait.h文件中的状态信息见下表:
—————————————————————————————————————–
宏定义 说明
—————————————————————————————————————–
WIFEXITED(stat_val) 如果子进程正常结束,它就取一个非零值(exit(n)的n值)
WEXITSTATUS(stat_val) 如果WIFEXITED非零,它返回子进程的退出码(exit(n)的n值)
WIFSIGNALED(stat_val) 如果子进程因为一个未捕获的信号而终止,它就取一个非零值
WTERMSIG(stat_val) 如果WIFSIGNALED非零,它返回一个信号代码
WIFSTOPPED(stat_val) 如果子进程终止,它就取一个非零值
WSTOPSIG(stat_val) 如果WIFSTOPPED非零,它返回一个信号代码
—————————————————————————————————————–
wait系统调用会使父进程暂停执行,直到它的一个子进程结束为止。
代码实例
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
pid_t pid;
char * message;
int n;
int exit_code;
printf("fork program starting\n");
pid = fork();
switch(pid)
{
case -1:
perror("fork failed");
exit(1);
case 0:
message ="This is the child";
n = 5;
exit_code = 37;/*子进程的退出码*/
break;
default:
message = "This is the parent";
n = 3;
exit_code = 0;/*父进程的退出码*/
break;
}
/*pid非0,在父进程执行*/
if(pid)
{
int stat_val;
pid_t child_pid;
/*父进程直到子进程退出后执行*/
child_pid = wait(&stat_val);
printf("Child process has finished: PID=%d\n",child_pid);
if(WIFEXITED(stat_val))/*子进程正常结束,输出子进程退出码,即exit_code=37*/
printf("Child exited with code %d\n", WEXITSTATUS(stat_val));
else/*子进程非正常结束*/
printf("Child terminated abnormally\n");
}
for(; n > 0; n--)
{
puts(message);
sleep(1);
}
exit(exit_code);
}
(注:如果父进程使用了wait函数,就算在子进程里使用了sleep函数,父进程也不能抢占cpu来用(即CPU不能调度父进程))
父进程通过wait系统调用把自己的执行挂起,直到子进程的状态信息出现为止。这将发生在子进程调用exit的时候;我们把它的退出码设置为37.
然后,父进程继续执行,通过测试wait调用的返回值确定子进程的已经正常结束,并从状态信息里提取出子进程的退出码。
运行效果见下图: