c - Linux 中的 Wait(&status) 系统调用

标签 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 加 5,生成 6,打印 6,然后返回 6 作为其退出状态。

在父级中,wait(&val) 成功返回后,val 包含 magic cookie 。子进程的退出状态编码在此 cookie 中,但必须使用宏 WIFEXITEDWIFSIGNALEDWEXITSTATUS 进行提取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/

相关文章:

C 程序卡住字长大于 6

c - #pragma omp parallel 用于降低速度而不是增加速度 - 在格子玻尔兹曼中

c - 人们觉得 C 指针有什么困难?

php - 如何使用 php 和 mysql 每秒处理数千个请求?

linux - 复制包含单词但不包含其他单词的文件。/grep 不使用 for 循环

c++ - 使用 malloc 分配比现有内存更多的内存

c - 编译代码时出现LNK2019错误

c++ - 有什么理由更喜欢 memset/ZeroMemory 而不是 WinAPI 结构的值初始化?

linux - 在 Linux 上展平目录结构时将数字附加到文件名

linux - 在 bash 中从占据终端整个宽度的破折号字符绘制一条水平线