【问题标题】:C, exit and pcntl_wait functions produce multiples of 256, why?C、exit和pcntl_wait函数产生256的倍数,为什么?
【发布时间】:2014-11-24 23:38:54
【问题描述】:

我正在编写一个测试,看看我是否可以可靠地确定退出代码的整数值 与wait

问题

1. 为什么退出代码乘以 256?
2.exit()wait()、操作系统还是其他乘法?

重现问题的代码。

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

// implementation is correct but irrelevant to the question
int compareInt(const void* a, const void* b); 

int main(void) {
    pid_t pids[6];
    int i;
    for (i = 0; i < 6; i++) {
        pid_t pid = fork();
        pids[i] = pid;
        if (pid == 0) {
            exit(i);
        }
    }

    int codes[6];
    do {
        i--;
        wait(&codes[i]);
    } while (i > 0);

    const size_t num_elem = 6;
    qsort(codes, num_elem, sizeof(int), compareInt);

    for (i = 0; i < 5; i++) {
        printf("%d, ", codes[i]);
    }
    printf("%d\n", codes[5]);
    return 0;
}

输出: 0, 256, 512, 768, 1024, 1280

事实证明我应该使用wifexited(), wifstopped(), wifsignaled(), wexitstatus(), wtermsig(), or wstopsig() 来确定退出状态。

此外,相同的行为在 PHP 中是可重现的(我第一次遇到它的地方)

$pids = [];
foreach (range(0, 5) as $i) {
    $pids[] = $pid = pcntl_fork();
    if ($pid === 0) {
        exit($i);
    }
}

$exit_codes = [];
do {
    pcntl_wait($exit_codes[]);
    array_pop($pids);
} while (count($pids) > 0);

sort($exit_codes);
echo implode(', ', $exit_codes) . "\n";

输出: 0, 256, 512, 768, 1024, 1280

如果有什么不同,我正在运行 Ubuntu 14.04,man wait 说我有 WAIT(2)

【问题讨论】:

    标签: php c exit ubuntu-14.04 exit-code


    【解决方案1】:

    您看到这些结果的原因是因为来自wait() 的返回值经过编码并包含诸如进程停止的方式和原因以及实际退出状态等信息;这就是为什么提供便利宏来检查返回值的某些部分的原因。

    WEXITSTATUS(status) 的定义可以在sys/wait.h 中找到,可能如下所示:

    #define WEXITSTATUS(status) (((status) & 0xff00) >> 8)
    

    或者这个:

    #define WEXITSTATUS(status) (((status) >> 8) & 0x000000ff)
    

    所以你看到乘法是因为:

    exit(1) -> 0x0100 (256)
    exit(2) -> 0x0200 (512)
    

    在 PHP 中你可以使用pcntl_wexitstatus() 来完成同样的事情;如果进程因信号而被终止,则不会有退出状态,您需要使用pcntl_wtermsig() 来确定用于终止它的信号。

    【讨论】:

    • 嗨,杰克,我无法立即理解您的答案(尽管它可能是正确的)。早上我会仔细研究它,如果您将资源链接到您找到宏定义的位置会有所帮助。
    • 嗨,杰克,感谢您的出色回答。这对我来说已经完全揭开谜底了。
    【解决方案2】:

    wait() 的返回值编码了几条信息。定义了宏来挑选结果并获得您需要的细节。例如WEXITSTATUS(result_of_wait).

    【讨论】:

    • 关于流程如何结束的基本信息 - 正常与否。阅读手册页以获取完整列表。
    猜你喜欢
    • 1970-01-01
    • 2014-10-05
    • 1970-01-01
    • 1970-01-01
    • 2016-06-29
    • 2016-12-08
    • 1970-01-01
    • 2014-01-16
    • 1970-01-01
    相关资源
    最近更新 更多