我有来自scipy.sparse.diags书籍和练习的代码,其中我需要用waitid()替换wait():
#include "apue.h"
#include <sys/wait.h>
int main(void)
{
pid_t pid;
int status;
if ((pid = fork()) < 0)
err_sys("fork error");
else if (pid == 0) /* child */
exit(7);
if (wait(&status) != pid) /* wait for child */
err_sys("wait error");
pr_exit(status); /* and print its status */
if ((pid = fork()) < 0)
err_sys("fork error");
else if (pid == 0) /* child */
abort(); /* generates SIGABRT */
if (wait(&status) != pid) /* wait for child */
err_sys("wait error");
pr_exit(status); /* and print its status */
if ((pid = fork()) < 0)
err_sys("fork error");
else if (pid == 0) /* child */
status /= 0; /* divide by 0 generates SIGFPE */
if (wait(&status) != pid) /* wait for child */
err_sys("wait error");
pr_exit(status); /* and print its status */
exit(0);
}
我试过了:
id_t pid;
siginfo_t info;
pid = fork();
// ...
waitid(P_PID, pid, &info, WNOHANG) // also tried with WNOWAIT
并得到waitid错误:参数无效。当我尝试:
waitid(P_PID, pid, &info, WEXITED)
我得到了所有三个waitid()调用的信号编号:17,其中原始代码的输出分别是信号7,6和8。我为什么得到#34;无效的论点&#34;以及如何强制系统生成信号7,6和8?
答案 0 :(得分:2)
waitid(P_ALL, 0, &info, WEXITED)
,info
类型为siginfo_t
,收集与wait(&status)
相同的子进程。它们的区别在于
siginfo_t *
的{{1}}参数及其解释 vs 。 waitid()
的{{1}}参数及其解释和您似乎希望每次都使用int *
等待某个特定的孩子,这就是:wait()
。
请注意,虽然waitid()
会返回成功收集的子流程的pid,但waitid(P_PID, pid, &info, WEXITED)
会在成功时返回wait()
。
另请注意,尽管waitid()
结构具有名为0
的成员,但它不等同于通过其第二个参数向调用者提供的值siginfo_t
。 si_status
是进程的实际退出代码,而wait()
提供的状态是几个不同字段的位掩码。您可以通过siginfo_t.si_status
宏从后者获得退出代码,但最好还是检查它是否实际上正常终止(wait()
)而不是发出信号(WEXITSTATUS()
)。< / p>
答案 1 :(得分:1)
来自man waitid:
The child state changes to wait for are specified by ORing one or more of the following flags in options:
WEXITED Wait for children that have terminated.
WSTOPPED Wait for children that have been stopped by delivery of a signal.
WCONTINUED Wait for (previously stopped) children that have been resumed by delivery of SIGCONT.
The following flags may additionally be ORed in options:
WNOHANG As for waitpid().
WNOWAIT Leave the child in a waitable state; a later wait call can be used to again retrieve the child status information.
和
EINVAL The options argument was invalid.
所以,你应该提供WEXITED。
编辑: 我在你的代码中添加了几个定义:
#define pr_exit(n) printf("%d\n", n)
#define err_sys perror
和#includes提供声明,我看到的是退出状态0x700,0x86和0x88,AFAICS是完全正确的。
这些退出状态分别是{正常退出状态7},{退出信号6}和{退出信号8}。请注意,由于信号7,退出状态7与退出不同。
(信号17是linux中的SIGCHLD。我不明白为什么你的孩子会以信号17退出。他们或者父母要么必须设置一个SIGCHLD处理程序才能引起这种情况.SIGCHLD有特定的和“不寻常”的行为。)
答案 2 :(得分:-1)
必须在选项中指定WCONTINUED,WEXITED或WSTOPPED中的至少一种 论点。
来自APUE书