waitpid()函数

waitpid函数

 作用同于wait,但可指定pid进程清理,可以不阻塞。

pid_t waitpid(pid_t pid,int *status,int options);成功:返回清理掉的子进程ID;失败:-1(无子进程)

特殊参数和返回情况:

参数pid:

       >0 回收指定ID的子进程

       -1 回收任意子进程(相当于wait)

       0 回收和当前调用waitpid一个组的所有子进程

       < -1 回收指定进程组内的任意子进程

返回0:参数3为WNOHANG,且子进程正在运行。

注意:一次wait或waitpid调用只能清理一个子进程,清理多个子进程需要用到循环

/***
loop_wait.c
***/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int main(int argc, char *argv[])
{
    int n = 5, i;                //默认创建5个子进程
    pid_t p, q;

    if(argc == 2){    
        n = atoi(argv[1]);
    }

    for(i = 0; i < n; i++)     {//出口1,父进程专用出口
        p = fork();
        if(p == 0) {
            break;            //出口2,子进程出口,i不自增
        } else if (i == 3){
            q = p;
        }
    }

    if(n == i){
        sleep(n);
        printf("I am parent, pid = %d\n", getpid(), getgid());
        //pid_t pid = waitpid(q, NULL, WNOHANG);
//        pid_t pid = wait(NULL);
        //printf("child pid = %d\n", pid);
        while(1);

    } else {
        sleep(i);
        printf("I'm %dth child, pid = %d, gpid=%d\n", 
                i+1, getpid(), getgid());
        while(1);
    }

    return 0;
}
/***
waitpid.c
***/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>

int main(void)
{
    pid_t pid, pid2, wpid;
    int flg = 0;

    pid = fork();
    pid2 = fork();

    if(pid == -1){
        perror("fork error");
        exit(1);
    } else if(pid == 0){        //son
        printf("I'm process child, pid = %d\n", getpid());
        sleep(5);                
        exit(4);
    } else {                    //parent
        do {
            wpid = waitpid(pid, NULL, WNOHANG);
            //wpid = wait(NULL);
            printf("---wpid = %d--------%d\n", wpid, flg++);
            if(wpid == 0){
                printf("NO child exited\n");
                sleep(1);        
            }
        } while (wpid == 0);        //子进程不可回收

        if(wpid == pid){        //回收了指定子进程
            printf("I'm parent, I catched child process,"
                    "pid = %d\n", wpid);
        } else {
            printf("other...\n");
        }
    }

    return 0;
}
/***
waitpid2.c
***/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>

int main(void)
{
    pid_t pid, pid2, wpid;
    int flg = 0;

    pid = fork();
    pid2 = fork();

    if(pid == -1){
        perror("fork error");
        exit(1);
    } else if(pid == 0){        //son
        printf("I'm process child, pid = %d\n", getpid());
        sleep(5);                
        exit(4);
    } else {                    //parent
        do {
            wpid = waitpid(pid, NULL, WNOHANG);
            //wpid = wait(NULL);
            printf("---wpid = %d--------%d\n", wpid, flg++);
            if(wpid == 0){
                printf("NO child exited\n");
                sleep(1);        
            }
        } while (wpid == 0);        //子进程不可回收

        if(wpid == pid){        //回收了指定子进程
            printf("I'm parent, I catched child process,"
                    "pid = %d\n", wpid);
        } else {
            printf("other...\n");
        }
    }

    return 0;
}
/***
waitpid3.c
***/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int main(int argc, char *argv[])
{
    int n = 5, i;                
pid_t p, q;

    if(argc == 2){    
        n = atoi(argv[1]);
    }
    q = getpid();

    for(i = 0; i < n; i++)     {
        p = fork();
        if(p == 0) {
            break;            
        } 
    }

    if(n == i){  // parent
        sleep(n);
        printf("I am parent, pid = %d\n", getpid());
        for (i = 0; i < n; i++) {
            p = waitpid(0, NULL, WNOHANG);
            printf("wait  pid = %d\n", p);
        }
    } else {
        sleep(i);
        printf("I'm %dth child, pid = %d\n", 
                i+1, getpid());
    }
    return 0;
}

waitpid:

       参1:    pid  > 0       指定进程id回收

                     pid = -1        回收任意子进程

                     pid = 0          回收本组任意子进程

                     pid < -1        回收该进程组的任意子进程

       参2:    status:

                     返回:成功:pid  失败 -1

                     status:传出参数

                     1: 阻塞等待子进程

                     2: 回收子进程资源

                     3:    获取子进程结束状态:1)WIFEXITED()真

                                                                      WEXITSTATUS()获取子进程退出状态

                                                               2)WIFSIGNALED() 真

                                                                      WTERMSIG()获取导致子进程终止的信号的                                                                                           编码

参3:    0 :(wait)阻塞回收

              WBNIOHANG:非阻塞回收(轮询)

返回值:       成功:pid  失败 -1  返回 0 值: 参3传WNOHANG,并且子进程尚未结束。

posted @ 2019-08-06 20:58  王清河  阅读(19185)  评论(0编辑  收藏  举报