• Linux 进程等待


    在2号手册里查wait()。wait()等待任意一个子进程的状态。

    wait()等待成功会返回该子进程的id,返回失败会返回-1:

    小实验     子进程的退出码

    子进程执行work(),父进程wait子进程。

    子进程跑完5秒之后就exit(0)退出。

    子进程跑的时候是run状态

    当子进程跑完,父进程接收到子进程的状态,即僵尸状态,然后父进程会跑10秒,10秒过后父进程也结束进程。

    代码如下:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. void work()
    7. {
    8. int cnt=5;
    9. while(cnt--)
    10. {
    11. printf("子进程开始启动:pid:%d,ppid:%d,cnt:%d\n",getpid(),getppid(),cnt);
    12. sleep(1);
    13. }
    14. }
    15. int main()
    16. {
    17. sleep(10);
    18. pid_t id=fork();
    19. if(id==0) //子进程
    20. {
    21. work();
    22. exit(0);
    23. }
    24. else //父进程
    25. {
    26. pid_t ret=wait(NULL);
    27. if(ret==id)
    28. {
    29. printf("wait success,pid:%d\n",getpid());
    30. }
    31. }
    32. sleep(10);
    33. return 0;
    34. }
    35. ~

    结论:子进程在跑,父进程就要进行阻塞等待。等子进程跑完,父进程才wait sucess,总结如下:

    waitpid()

    用法:

     三个参数,重点讲一下  stauts

    status是输出型参数,所谓输出型参数需要用户自己定义变量,然后传参,操作系统接收这个参数经过操作之后再返回给用户级变量

    如下,定义一个int型变量,变量名为status,取地址传参,然后等如果父进程等待子进程之后就把status的值打印出来看看:

    结果如下:

    status是一个整形,有32位,分为高八位和低八位:

     如果进程正常退出,就返回低八位的0,高八位的退出状态。

    如果异常退出,就返回低七位的终止信号,为什么不是低八位呢? 低八位的第一位是core dump标志,所以只返回低七位。

    如下,我们把子进程的退出码改为exit(10),再让父进程去等待:
    运行结果:status为2560。

    因为退出码10的二进制为1010,又因为异常所以在高八位,如下:

    转化为十进制就是2560;








    exit sign为stautus的信号退出码,exit code为status的进程退出码:

    1. printf("wait success,pid:%d,status返回码:%d,
    2. exit sign:%d ,exit code:%d\n",getpid(),ret,
    3. status&0x7F,(status>>8)&0xFF);

    为什么exit sign是 status&0x7F?

    因为信号退出码在低七位  7是3个1,F是4个1,合起来就是7个1,&7个1就把低七位保留,其他位全变0

    同理,exit code为高八位  

    运行结果:

    退出信号为0,退出码为10、

    如果我们把子进程的退出码改为正常退出码,即0,再跑,就会退出信号为0,退出码为0:

    我们给子进程写一个除0错误:

     退出信号会显示8:

    我们让子进程出现空指针错误:

    退出信号为11:11就是段错误:

    第二个实验  手动退出

    我们让子进程不要退出了,一直运行:

    此时运行之后子进程就会一直跑,然后我们输入kill -9 pid终止进程,进程退出信号会显示9:

    小结

    父进程得到子进程的退出结果实际上是调用stautus这个整型变量,可以用一个指针解引用即可得到status。

    WIFEXITED    WEXITSTAUS

     用这两个宏就我们就可以不用关注返回值,宏会自己获取子进程的返回值。

    调用WIFEXITED获取是否正常退出,如果为假,直接输出else里面的异常。

    如果为真,就调用WEXITSTAUS获取子进程的退出码并打印出来。

    我们可以先搞一个异常出来,把子进程死循环:

    运行:

    我们再把子进程改为正常的再运行:

    非阻塞轮巡/非阻塞等待

    与阻塞式等待相对。

    阻塞式等待父进程什么事情也不干,就在那等着子进程返回值。

    阻塞式等待可以干自己的事情,等子进程返回的时候接收一下就可以了。

  • 相关阅读:
    SpringBoot对Spring MVC都做了哪些事?
    springboot项目controller方法参数校验异常处理
    水果店圈子:水果店的风险大吗,做水果店有风险吗
    【pytorch笔记】第三篇 Tensorboard使用
    企业如何实时监管员工聊天&转账行为
    使用CURAND在GPU和CPU上生成随机数的示例
    睡前随记-1
    Linux的shell编程易错点解析(for循环和ls命令)
    微信小程序 java家庭个人收支理财记账本springboot
    Spring02
  • 原文地址:https://blog.csdn.net/m0_65143871/article/details/134550787