waitid()错误:参数无效

时间:2015-05-12 18:44:45

标签: c linux

我有来自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?

3 个答案:

答案 0 :(得分:2)

<waitid(P_ALL, 0, &info, WEXITED)info类型为siginfo_t,收集与wait(&status)相同的子进程。它们的区别在于

  1. siginfo_t *的{​​{1}}参数及其解释 vs waitid()的{​​{1}}参数及其解释和
  2. 这两个功能的含义&#39;返回值。
  3. 您似乎希望每次都使用int *等待某个特定的孩子,这就是:wait()

    请注意,虽然waitid()会返回成功收集的子流程的pid,但waitid(P_PID, pid, &info, WEXITED)会在成功时返回wait()

    另请注意,尽管waitid()结构具有名为0的成员,但它不等同于通过其第二个参数向调用者提供的值siginfo_tsi_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书