循环创建n个进程,指定每个进程做不同任务,通过wait和waitpid函数回收进程
可以看一下 子进程回收(wait和waitpid)
wait函数:
1,该函数有三个功能:
① 阻塞等待子进程退出
② 回收子进程残留资源
③ 获取子进程结束状态(退出原因)。
函数原型:pid_t wait(int *status);
返回值:成功:清理掉的子进程ID;失败:-1 (没有子进程)
2,当进程终止时,操作系统的隐式回收机制会:
1.关闭所有文件描述符
2.释放用户空间分配的内存。内核的PCB仍存在。其中保存该进程的退出状态。(正常终止→退出值;异常终止→终止信号)
3,wait函数传出参数status来保存进程的退出状态。借助宏函数来进一步判断进程终止的具体原因。宏函数可分为如下三组:
1. WIFEXITED(status) 为非0 → 进程正常结束
WEXITSTATUS(status) 如上宏为真,使用此宏 → 获取进程退出状态 (exit的参数)
2.WIFSIGNALED(status) 为非0 → 进程异常终止
WTERMSIG(status) 如上宏为真,使用此宏 → 取得使进程终止的那个信号的编号。
3.WIFSTOPPED(status) 为非0 → 进程处于暂停状态
WSTOPSIG(status) 如上宏为真,使用此宏 → 取得使进程暂停的那个信号的编号。
WIFCONTINUED(status) 为真 → 进程暂停后已经继续运行
注意:前两组最为重要
waitpd函数:
函数原型:pid_t waitpid(pid_t pid, int *status, in options);
返回值:成功:返回清理掉的子进程ID;失败:-1(无子进程); 返回0:参3为WNOHANG,且子进程正在运行。
特殊参数和返回情况:
参数pid:
> 0 回收指定ID的子进程
-1 回收任意子进程(相当于wait)
0 回收和当前调用waitpid一个组的所有子进程
< -1 回收指定进程组内的任意子进程
主要用的是 >0 和 -1。
注意:一次wait或waitpid调用只能清理一个子进程,清理多个子进程应使用循环。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
int main()
{
int i = 0;
for( i = 0; i < 5; i++ ){
pid_t pid = fork();
if( pid > 0 ){ //parent
printf("parent = %d %d %d\n", getpid(), getppid(), pid );
}else if( pid == 0 ){
//printf("child = %d %d\n", getpid(), getppid() );
break;
}else{
perror("fork error");
exit( 1 );
}
}
if( i == 0 ){
printf("i = %d, pid = %d\n", i, getpid() );
abort();
}
if( i == 1 ){
printf("i = %d, pid = %d\n", i, getpid() );
exit( 100 );
}
if( i == 2 ){
printf("i = %d, pid = %d\n", i, getpid() );
char *p = NULL;
*p = 'a';
}
if( i == 3 ){
printf("i = %d, pid = %d\n", i, getpid() );
return 0;
}
if( i == 4 ){
printf("i = %d, pid = %d\n", i, getpid() );
float p = 10 / 0;
}
if( i == 5 ){
int j = 0;
for( j = 0; j < i; j++ ){
int status = 0;
wait( &status );
if(WIFEXITED(status)) { //WIFEXITED 宏的释义: wait if exit ed
printf("子进程返回信息码:%d\n",WEXITSTATUS(status));
}else if(WIFSIGNALED(status)){
printf("子进程信号中断返回信息码:%d\n",WTERMSIG(status));
}else if(WIFSTOPPED(status)){
printf("子进程暂停返回信息码:%d\n",WSTOPSIG(status));
}else{
printf("其他退出信息!\n");
}
}
}
return 0;
}