系统编程:wait(&status) 的 return 值
Systems programming: wait(&status)'s return value
在学习分叉和管道时,我遇到了以下优秀教程:https://www.cs.rutgers.edu/~pxk/416/notes/c-tutorials/pipe.html
但是,本教程讨论了如何在最后一个父进程生成的 2 个子进程之间建立管道。虽然它在这方面做得很好,但有一行代码让我困惑了一段时间:
while ((pid = wait(&status)) != -1) /* pick up all the dead children*/
fprintf(stderr, "process %d exits with %d\n", pid, WEXITSTATUS(status));
exit(0);
我对 wait(&status)
真的很困惑(是的,我已经阅读了 http://linux.die.net/man/2/wait 的手册页)。我们只是声明一个int status
,从来没有真正给它一个值,只是把它传递给等待。此状态是否在 wait()
函数中透明设置?
手册页说:
wait(): on success, returns the process ID of the terminated child; on error, -1 is returned.
所以在上面的几行代码中,while循环在wait(&status)
returns -1时退出。这很刺耳:有没有错误,为什么?我们如何确保父级一直旋转直到其所有子级正确终止? 'status' 到底是什么,它是如何设置的?
编辑:要补充一点,该程序确实编译并且 运行 完美。
当您调用 wait(&status)
时,&
表示 "take the address of" status
。
因此,您将 指针 传递给 status
,并且 而不是 它的 值.
wait
例程将使用此指针在 status
中填充 return 之前的值。这是除了函数的return值。
因此,status
将在调用 之后有效。
在调用之前不需要设置status
的原因是wait
只设置 一个值,不 尝试预先使用该值。
status
包含一些东西。 child 程序是否正常退出(例如退出代码 0,或错误代码为 [say] 1)。程序是否被信号终止(例如 SIGSEGV
)。 child 是否是 "stopped" [由 strace
、gdb
和其他调试器使用]。如果您查看 wait(2)
联机帮助页,那里有一大堆 "helper" 宏,例如 WIFEXITED
、WEXITSTATUS
、WIFSIGNALED
、WTERMSIG
,等等,可以帮助理解 status
值
至于return值,-1
表示错误。但是,[全局 errno
] 中的错误可能是 ECHILD
。这只是意味着 parent 进程中没有更多的 children 剩余。 (即)程序已经等待并且 "reaped" 之前通过 fork
.
启动的所有 children
在学习分叉和管道时,我遇到了以下优秀教程:https://www.cs.rutgers.edu/~pxk/416/notes/c-tutorials/pipe.html
但是,本教程讨论了如何在最后一个父进程生成的 2 个子进程之间建立管道。虽然它在这方面做得很好,但有一行代码让我困惑了一段时间:
while ((pid = wait(&status)) != -1) /* pick up all the dead children*/
fprintf(stderr, "process %d exits with %d\n", pid, WEXITSTATUS(status));
exit(0);
我对 wait(&status)
真的很困惑(是的,我已经阅读了 http://linux.die.net/man/2/wait 的手册页)。我们只是声明一个int status
,从来没有真正给它一个值,只是把它传递给等待。此状态是否在 wait()
函数中透明设置?
手册页说:
wait(): on success, returns the process ID of the terminated child; on error, -1 is returned.
所以在上面的几行代码中,while循环在wait(&status)
returns -1时退出。这很刺耳:有没有错误,为什么?我们如何确保父级一直旋转直到其所有子级正确终止? 'status' 到底是什么,它是如何设置的?
编辑:要补充一点,该程序确实编译并且 运行 完美。
当您调用 wait(&status)
时,&
表示 "take the address of" status
。
因此,您将 指针 传递给 status
,并且 而不是 它的 值.
wait
例程将使用此指针在 status
中填充 return 之前的值。这是除了函数的return值。
因此,status
将在调用 之后有效。
在调用之前不需要设置status
的原因是wait
只设置 一个值,不 尝试预先使用该值。
status
包含一些东西。 child 程序是否正常退出(例如退出代码 0,或错误代码为 [say] 1)。程序是否被信号终止(例如 SIGSEGV
)。 child 是否是 "stopped" [由 strace
、gdb
和其他调试器使用]。如果您查看 wait(2)
联机帮助页,那里有一大堆 "helper" 宏,例如 WIFEXITED
、WEXITSTATUS
、WIFSIGNALED
、WTERMSIG
,等等,可以帮助理解 status
值
至于return值,-1
表示错误。但是,[全局 errno
] 中的错误可能是 ECHILD
。这只是意味着 parent 进程中没有更多的 children 剩余。 (即)程序已经等待并且 "reaped" 之前通过 fork
.