
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *wstatus, int options);
功能:回收指定进程号的子进程,可以设置是否阻塞。
参数:
- pid:
pid > 0 : 表示某个子进程的pid
pid = 0 : 表示回收当前进程组的所有子进程
例如:回收当前进程组(A)的所有子进程:BC都被回收
pid = -1 : 表示回收所有的子进程,相当于 wait() (最常用)例如:回收A的所有子进程:BCD都被回收
pid < -1 : 表示某个进程组的组id的绝对值,回收指定进程组中的子进程
- options:设置阻塞或者非阻塞
0 : 阻塞
WNOHANG : 非阻塞
- 返回值:
> 0 : 返回子进程的id
= 0 : options=WNOHANG, 表示还有子进程活着
= -1 :错误,或者没有子进程了
waitpid.c
/*
    #include <sys/types.h>
    #include <sys/wait.h>
    pid_t waitpid(pid_t pid, int *wstatus, int options);
        功能:回收指定进程号的子进程,可以设置是否阻塞。
        参数:
            - pid:
                pid > 0 : 表示某个子进程的pid
                pid = 0 : 表示回收当前进程组的所有子进程    
                pid = -1 : 表示回收所有的子进程,相当于 wait()  (最常用)
                pid < -1 : 表示某个进程组的组id的绝对值,回收指定进程组中的子进程
            - options:设置阻塞或者非阻塞
                0 : 阻塞
                WNOHANG : 非阻塞
            - 返回值:
                > 0 : 返回子进程的id
                = 0 : options=WNOHANG, 表示还有子进程活着
                = -1 :错误,或者没有子进程了
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main() {
    // 有一个父进程,创建5个子进程(兄弟)
    pid_t pid;
    // 创建5个子进程
    for(int i = 0; i < 5; i++) {
        pid = fork();
        if(pid == 0) {
            break;
        }
    }
    if(pid > 0) {
        // 父进程
        while(1) {
            printf("parent, pid = %d\n", getpid());
            sleep(1);
            int st;
            /*
                - pid:
                      pid = -1 : 回收所有的子进程,相当于 wait()  (最常用)
			    - options:设置阻塞或者非阻塞
                      0 : 阻塞
                      WNOHANG : 非阻塞
            */
            // int ret = waitpid(-1, &st, 0);
            int ret = waitpid(-1, &st, WNOHANG);
            
            /*
                pid_t waitpid(pid_t pid, int *wstatus, int options);
                    - 返回值:
                          > 0 : 返回子进程的id
                          = 0 : options=WNOHANG, 表示还有子进程活着
                          = -1 :错误,或者没有子进程了
            */
            if(ret == -1) {
                break;
            } else if(ret == 0) {
                // 说明还有子进程存在
                continue;
            } else if(ret > 0) {
                //说明回收到了具体的子进程的id
                if(WIFEXITED(st)) {
                    // 是不是正常退出
                    printf("退出的状态码:%d\n", WEXITSTATUS(st));
                }
                if(WIFSIGNALED(st)) {
                    // 是不是异常终止
                    printf("被哪个信号干掉了:%d\n", WTERMSIG(st));
                }
                printf("child die, pid = %d\n", ret);
            }
           
        }
    } else if (pid == 0){
        // 子进程
         while(1) {
            printf("child, pid = %d\n",getpid());    
            sleep(1);       
         }
        exit(0);
    }
    return 0; 
} gcc waitpid.c -o waitpid
./waitpid
kill -9 33355
kill -9 33356
kill -9 33357
kill -9 33358
kill -9 33359

都被干掉以后,回到 int ret = waitpid(-1,&st,WNOHANG);发现没有子进程了,ret返回-1,然后break掉,父进程结束!!!整个程序运行结束
 


















