我正在编写一个测试,看看能否可靠地确定退出代码的整数值
与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)
答案 0 :(得分:11)
您看到这些结果的原因是因为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()
来确定用于杀死它的信号。
答案 1 :(得分:1)
wait()
的返回值对几条信息进行编码。定义了宏来挑选结果并获得您需要的尼特。例如WEXITSTATUS(result_of_wait)
。