Return 来自带有 fork() 的 exit() 奇怪地移位

Return from exit() with fork() is weirdly bitshifted

我在 C 中有一个代码,它有时会自行分叉,每个分叉都会做一些事情然后 returns 一个错误代码。目前,每个子进程 returns 其 ID (0..n).

void other(int numero){
    ...
    exit(numero);
}

int main(...){
    for(int i = 0; i < 6; i++){
        if(fork() == 0){
            other(i);
        }
    }
    int order[6];
    for(int i = 0; i < 6; i++){
        int code;
        waitpid(0, &code, 0);
        order[i] = code; // <-- HERE
    }
}

奇怪的是,这个 returns 是真实值的倍数。通过替换我用 :

标记的行
order[i] = code >> 8;

我设法得到了 0..5 的预期结果。但是,我真的不明白为什么会这样。我希望这是因为某种类型的问题,但我没有看到它,我一直在使用整数。

order[i] = code; 的正确替换是 order[i] = WEXITSTATUS(code); 另外请注意,即使进程没有退出,waitpid 也可以 return;你应该使用 WIFEXITED 来确保它做到了。

来自man 2 waitpid

   If wstatus is not NULL, wait() and waitpid() store status information
   in the int to which it points.  This integer can be inspected with
   the following macros (which take the integer itself as an argument,
   not a pointer to it, as is done in wait() and waitpid()!):

    WEXITSTATUS(wstatus)
          returns the exit status of the child.  This consists of the
          least significant 8 bits of the status argument that the child
          specified in a call to exit(3) or _exit(2) or as the argument
          for a return statement in main().  This macro should be
          employed only if WIFEXITED returned true.

你应该使用那里列出的各种宏,比如你的例子中的 WEXITSTATUS,来理解 wstatus。除了使用它们之外,只有将 wstatus 视为不透明的 blob 才是安全的(除了它为 0 的特殊情况)。

您应该使用 sys/wait.h 中的 W* 宏来解释退出状态。

请参阅 waitpid 联机帮助页。

就原始值而言,您只能指望 status==0 意味着 WIFEXITED(status) && WEXITSTATUS(status)==0(请参阅描述此特殊保证的 http://pubs.opengroup.org/onlinepubs/9699919799/functions/waitpid.html)。