zoukankan      html  css  js  c++  java
  • 进程-(4)

    wait()、waitpid()函数

    简介
    1)当一个进程正常或异常终止时,内核就向其父进程发送SIGCHLD信号。父进程可以忽略该信号,或者提供一个该该信号的处理函数。默认情况下,系统会忽略该信号
    2)如果父进程调用了wait或waitpid时
    如果其子进程都还在运行,则阻塞
    如果一个子进程已终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回
    如果它没有任何子进程,则立即返回


    两个函数的区别


    在一个子进程终止前,wait使其调用者阻塞,而waitpid 很多选择
    如果一个子进程已经终止,并且是僵死进程,wait会立即返回并取得该子进程的状态,否则阻塞。

    wait()和waitpid()可以让父进程等待子进程的结束,效果:父进程阻塞,子进程运行,直到子进程结束。
    wait()等待方式比较单一,waitpid()等待方式有更多的选择。

    wait() 函数:

    pid_t wait(int* status)
    等待任意一个子进程结束,status 会存储结束子进程的信息(退出码,是否正常退出等),返回值是结束子进程的PID。会导致父进程一直阻塞,直到有一个子进程结束为止(包括僵尸子进程)。
    也就是说wait()函数,参数是退出码,返回值是结束的子进程的pid;wait() 可以回收僵尸子进程;
    宏函数:WIFEXITED(status)可以判断是否正常退出,如果正常退出返回真,而WEXITSTATUS(status)取退出码(exit(值))。

    Waitpid() 函数


    如果进程有几个子进程,那么要等待指定的进程终止,可使用waitpid
    pid_t waitpid(pid_t pid,int* status,int option)
    参数:pid参数
    ==-1,等待任意子进程,与wait等效
    >0 等待指定子进程
    ==0 等待其组ID等于调用进程组ID的任一子进程
    <-1 等待其组ID等于pid绝对值的任一子进程
    option可以指定是否阻塞方式等待,WNOHANG就相当于非阻塞方式等待。
    返回:阻塞方式:返回结束子进程的PID,失败返回-1 。
    WNOHANG方式:返回结束子进程的PID,如果没有子进程结束,返回0,失败返回-1。


    例子:wait() 函数的调用
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <stdlib.h>

    int main()
    {
    pid_t pid = fork();
    if(pid == 0){//子进程分支
    printf("子进程%d开始运行 ",getpid());
    sleep(3);
    printf("子进程结束运行 ");
    exit(100); }
    printf("父进程等待子进程的结束 ");
    int status;
    pid_t wpid = wait(&status);
    printf("等待结束 ");
    printf("wpid=%d ",wpid);
    if(WIFEXITED(status))
    printf("子进程正常结束,退出码:%d ",
    WEXITSTATUS(status));
    }

    结果如下:
    父进程等待子进程的结束
    子进程20304开始运行
    子进程结束运行
    等待结束
    wpid=20304
    子进程正常结束,退出码:100

    上面的结果表明:因为不知道父子进程,那个先开始,所以,在子进程中,需要sleep一下,让子进程等等;
    然后,好查看父进程的效果;
    而且,子进程有调用函数exit,则他会在调用函数处,会自动结束子进程;从而,后续只运行父进程,查看的更加清晰;

    例子2:开始显示waitpid()的效果
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/wait.h>
    #include <unistd.h>

    int main(){
    pid_t pid1,pid2;
    pid1 = fork();
    if(pid1 > 0) pid2 = fork();//只有父进程能执行
    if(pid1 == 0){ //子进程一分支
    printf("子进程一%d开始运行 ",getpid());
    sleep(3); printf("子进程一结束 ");
    exit(100); }
    if(pid2 == 0){//子进程二分支
    printf("子进程二%d开始运行 ",getpid());
    sleep(1); printf("子进程二结束 ");
    exit(200); }
    int status;
    waitpid(pid1,&status,0);//阻塞等待
    if(WIFEXITED(status)) printf("EXIT=%d ",
    WEXITSTATUS(status));//查vfork()手册并写测试代码
    }

    [root@aiyq195 day07]# vi waitpid3.c
    [root@aiyq195 day07]# gcc waitpid3.c -o waitpid3
    [root@aiyq195 day07]# ./waitpid3
    子进程一23175开始运行
    子进程二23173开始运行
    子进程二结束
    子进程一结束
    EXIT=100

    例子4:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/wait.h>
    #include <unistd.h>

    int main(){
    pid_t pid1,pid2;
    pid1 = fork();
    if(pid1 > 0) pid2 = fork();//只有父进程能执行
    if(pid1 == 0){ //子进程一分支
    printf("子进程一%d开始运行 ",getpid());
    sleep(3); printf("子进程一结束 ");
    exit(100); }
    if(pid2 == 0){//子进程二分支
    printf("子进程二%d开始运行 ",getpid());
    sleep(1); printf("子进程二结束 ");
    exit(200); }
    int status;
    waitpid(-1,&status,0);//阻塞等待
    if(WIFEXITED(status)) printf("EXIT=%d ",
    WEXITSTATUS(status));//查vfork()手册并写测试代码
    }

    [root@aiyq195 day07]# vi waitpid3.c
    [root@aiyq195 day07]# gcc waitpid3.c -o waitpid3
    [root@aiyq195 day07]# ./waitpid3
    子进程一23175开始运行
    子进程二23173开始运行
    子进程二结束
    EXIT=100
    子进程一结束
    说明如果没有指定waitpid,的pid参数,给以-1为参数,则会造成父进程接受到任意一个子进程结束的pid结束信息,就返回;

    例子5:

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

    int main(){
    pid_t pid1,pid2;
    pid1 = fork();
    if(pid1 > 0) pid2 = fork();//只有父进程能执行
    if(pid1 == 0){ //子进程一分支
    printf("子进程一%d开始运行 ",getpid());
    sleep(3); printf("子进程一结束 ");
    exit(100); }
    if(pid2 == 0){//子进程二分支
    printf("子进程二%d开始运行 ",getpid());
    sleep(1); printf("子进程二结束 ");
    exit(200); }
    int status;
    waitpid(-1,&status,WNOHANG);//阻塞等待
    if(WIFEXITED(status)) printf("EXIT=%d ",
    WEXITSTATUS(status));//查vfork()手册并写测试代码
    }


    [root@aiyq195 day07]# vi waitpid3.c
    [root@aiyq195 day07]# gcc waitpid3.c -o waitpid3
    [root@aiyq195 day07]# ./waitpid4
    子进程一23175开始运行
    EXIT=0
    子进程二23173开始运行
    子进程二结束
    子进程一结束

    如果waitpid() 的option 参数,使用WNOHANG 的时候,如果子进程没有立马返回,相应码信息,则直接过去,返回0;

  • 相关阅读:
    上行带宽和下行带宽是什么意思?各有什么作用?
    Windows下安装OpenSSL及其使用
    openssl的证书格式转换
    科普:TLS、SSL、HTTPS以及证书(转)
    ELK日志分析平台搭建全过程
    【周末学习】五格货栈的互联网思维:如何不花一分钱实现...
    励志语录
    highstock K线图 深入研究
    关于highstock横坐标的一些的一些说明(1)使用UTC时间
    HighCharts/Highstock使用小结,使用汉化及中文帮助文档
  • 原文地址:https://www.cnblogs.com/aiyq195/p/6428025.html
Copyright © 2011-2022 走看看