我正在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
答案 0 :(得分:-1)
在孩子中,你的程序只需添加1到5,产生6,打印6,然后返回6作为其退出状态。
在父级中,wait(&val)
成功返回后,val
包含magic cookie。子项的退出状态在此Cookie中编码,但必须使用宏WIFEXITED
,WIFSIGNALED
,WEXITSTATUS
,WTERMSIG
等提取它们。以数字方式增加Cookie没有意义。如果您知道W宏在特定操作系统上如何工作,那么以数字方式打印它会产生您可以可以解释的东西,但除了调试之外,您不应该这样做。
父程序中打印的父项号1537更容易理解为十六进制:0x0601。这意味着在您递增之前,原始cookie值为0x0600。在Linux上,WIFEXITED(0x0600)
为真,WEXITSTATUS(0x0600) == 6
。在任何其他操作系统上,它可能或可能不同意。
假设您打算为打印6和7生成Rube Goldberg machine,更好的方法是这样:
#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;
}