我正在 Linux 中执行此程序,但我无法理解使用 wait(&val) 系统调用的程序的输出
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
int main(void)
{
int val = 5;
if (fork())
wait(&val);
val++;
printf("%d\n", val);
return val;
}
huzee98@ubuntu:~$ ./task2a
6
1537
最佳答案
在子进程中,您的程序只需将 1 加 5,生成 6,打印 6,然后返回 6 作为其退出状态。
在父级中,wait(&val)
成功返回后,val
包含 magic cookie 。子进程的退出状态编码在此 cookie 中,但必须使用宏 WIFEXITED
、WIFSIGNALED
、WEXITSTATUS
、 进行提取WTERMSIG
等。以数字方式增加 cookie 是没有意义的。如果您知道 W 宏在您的特定操作系统上如何工作,则以数字方式打印出来会产生您可以在心里解释的内容,但除了调试某些内容之外,您不应该这样做。
父级在程序中打印的数字 1537,用十六进制表示更容易理解:0x0601。这意味着在您递增之前,原始 cookie 值是 0x0600。在 Linux 上,WIFEXITED(0x0600)
为 true,并且 WEXITSTATUS(0x0600) == 6
。在任何其他操作系统上,它的含义可能相同,也可能不同。
假设您的意图是生成 Rube Goldberg machine对于打印 6 然后打印 7,更好的方法是这样的:
#include <assert.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
int val, status;
pid_t pid = fork();
if (pid == -1) {
perror("fork");
return 1;
}
if (pid == 0) {
val = 5;
val++;
printf("%d\n", val);
return val;
}
/* we are the parent if we get here */
if (wait(&status) != pid) {
perror("wait");
return 1;
}
if (!WIFEXITED(status)) {
assert(WIFSIGNALED(status));
printf("child process killed by signal %d\n", WTERMSIG(status));
return 1;
}
val = WEXITSTATUS(status);
val++;
printf("%d\n", val);
return 0;
}
关于c - Linux 中的 Wait(&status) 系统调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50240788/