在linux中等待(& status)系统调用

时间:2018-05-08 19:12:36

标签: c linux

我正在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 个答案:

答案 0 :(得分:-1)

在孩子中,你的程序只需添加1到5,产生6,打印6,然后返回6作为其退出状态。

在父级中,wait(&val)成功返回后,val包含magic cookie。子项的退出状态在此Cookie中编码,但必须使用宏WIFEXITEDWIFSIGNALEDWEXITSTATUSWTERMSIG等提取它们。以数字方式增加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;
}