【问题标题】:Why does my output differ for this code snippet?为什么我的输出与此代码段不同?
【发布时间】:2017-01-03 10:11:43
【问题描述】:

我最近开始学习操作系统课程。我遇到了这个问题,我需要弄清楚输出是什么。这是代码 -

int main() {
  int val = 5;
  if(fork()) {
    wait(&val);
  }
  val++;
  printf("%d ", val);
  return val;
}

这个帖子之前已经在 SO 上回答过 - Explain this code's working; how the child process returns values and where?
我了解返回值如何从子进程返回到 val,然后在父进程中递增并打印,根据该逻辑的输出实际上应该是 6 7

但是当我尝试自己执行代码时,我似乎得到了完全不同的东西。我得到一个输出 6 1537。如果我删除增量,我得到输出 - 6 1280
这意味着返回的值是 val*256 而不仅仅是 val(这与我链接的答案不符)。我曾尝试在互联网上寻找解释,但似乎找不到答案。如果有人能解释这里发生的事情,那真的很有帮助。

【问题讨论】:

  • 您的代码缩进与实际情况不同。
  • 您似乎缺少一个右大括号(或有一个太多的左大括号)。
  • 是的,我忘记在此处添加右括号。
  • 另请参阅:Exit codes bigger than 255 — possible?,对于 POSIX 系统,exit()waitpid(),以及我的 cmets 12

标签: c operating-system fork system-calls


【解决方案1】:

wait() 系统调用不仅将来自子进程的返回值放入 wait() 的返回值中。事实上,只有低 8 位是返回值,高位是状态标志,指示孩子如何退出(例如通过信号)。要从孩子那里获取返回值,请使用:

val = WEXITSTATUS(val);

wait() 之后。

【讨论】:

  • 我确实遇到过这个。所以基本上不使用 WEXITSTATUS 返回的值总是会移位 8 位?
  • 经典上,16位状态的高8位是退出状态,低8位是进程是否正常退出的指示(这种情况下高位-顺序位是有意义的)或作为信号的结果退出(在这种情况下,您可以确定哪个信号导致死亡,以及是否创建了核心转储,但高位不包含有用的信息)。这与您所描述的相反。
  • 话虽如此,也许混淆在于传递给exit() 的内容与waitpid()wait() 返回的内容之间。传递给exit() 的值的低8 位可供父进程使用。但是,waitpid()wait() 返回的值通常在 15-8 位中包含那些退出位,而 7-0 位包含信号信息(尽管 POSIX 强制要求该布局 - 但即使这样,通常也会观察到)。
猜你喜欢
  • 2016-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-07
相关资源
最近更新 更多