> 文章列表 > Linux 进程:进程退出返回值的获取

Linux 进程:进程退出返回值的获取

Linux 进程:进程退出返回值的获取

目录

  • 一、对输出参数status的理解
  • 二、获取进程退出返回值
    • 1.位运算
      • (1)异常退出码
      • (2)进程返回值
    • 2.宏函数

  我们常使用函数 waitwaitpid 来执行进程等待的功能:处理退出的子进程并释放资源,防止子进程变成僵尸进程。而这两个函数都有一个输出参数status,我们可以通过这个输出参数来获取进程的退出返回值。但是进程的退出返回值并不是直接将status解引用就可以得到的,详细原因且看下文。

  • pid_t wait(int *status);
  • pid_t waitpid(pid_t pid, int *status, int options);

一、对输出参数status的理解

  在wait和waitpid中,输出参数status存储了子进程的退出返回值,但是并不是直接解引用就可以得到子进程的退出返回值。

  status解引用后是int型变量,占据四个字节的内存空间。但它的四个字节并不是都存储着进程的退出返回值。如图所示:我们给每个字节从高地址到低地址依次编号:1、2、3、4字节。

4字节

  1、2字节在这里我们用不上,因此不做讨论。

  3号字节存储的是子进程的退出返回值,也就是说,只有8个比特位才是用来存储进程退出返回值的。

  4号字节的低7位存储异常退出码(当程序异常退出时,异常退出码就可以表示程序是因为什么异常而退出的),如果异常退出码不是0说明进程是异常退出。4字节的最高1位是coredump标志,这里不作讨论。

  在获取子进程的退出返回值之前,首先需要获取异常退出码,判断异常退出码是不是0。如果是0,说明是正常退出,可以去获取进程的退出返回值了;如果异常退出码不是0,说明是异常退出,那么就没有必要获取进程的退出返回值了。

二、获取进程退出返回值

 我们有两种方式可以获取status中的退出返回值和异常退出码:

  • 位运算
  • 宏函数

1.位运算

(1)异常退出码

  因为异常退出码占用的是4号字节中的低7位,因此我们可以通过(*status)和16进制数(0x7f)进行与运算得到异常退出码。

  如图:第一行是status解引用后的数,第二行是0x7f的二进制表示,不管高25位是什么数字,只要和0相与都变成0,而低7位依然保持原样,因此可以得到异常退出码。

异常退出码

(2)进程返回值

  进程返回值占用的是3号字节中的8个bit,因此需要把(*status)进行右移8位,如图所示。

  这样进程返回值就变成了低8位,然后使用上面的方法,把右移后的数据和16进制数(0xff)相与得到进程返回值。

右移8位

2.宏函数

   WIFEXITED(status) 等价于 ( (*status)&(0x7f) )==0 ,当异常退出码是0,宏函数返回true,表示进程的退出返回值有意义,可以去获取。

  WEXITSTATUS(status) 等价于 ( (*status >> 8)&(0xff) ),这样直接就可以得到进程的退出返回值。