【问题标题】:Which one to choose waitpid/wait/waitid?选择waitpid/wait/waitid哪一个?
【发布时间】:2014-04-08 09:53:45
【问题描述】:

我想在 fork 后在子进程中使用 execl。 execl 将执行大约需要 120 秒时间的脚本。我尝试了几乎所有与 waitpid、wait 和 waitid 的组合以及不同的参数(0、WNOHANG 等),但在所有情况下我都得到 -1 返回值。所以我想知道何时需要使用哪个等待功能?所以我可以专注于一个等待函数来让它工作。

我从日志中观察到的另一件有趣的事情是,当我在子进程中什么都不做时,它会将我的父线程显示为孤立的。不知道怎么可能?我的父线程如何成为孤立线程?

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main(void)
{
    pid_t Checksum_pid = fork();

    if (Checksum_pid < 0)
        printf("Fork Failed\n");
    else if (Checksum_pid == 0)
    {
        execl("/bin/ls","ls",(char *)NULL) ;
        exit(EXIT_FAILURE);
    }
    else
    {
        int childStatus;
        pid_t returnValue = waitpid(Checksum_pid, &childStatus, 0);

        if (returnValue > 0)
        {
            if (WIFEXITED(childStatus))
                printf("Exit Code: %d\n", WEXITSTATUS(childStatus));

        }
        else if (returnValue == 0)
            printf("Child process still running\n");
        else
        {
            if (errno == ECHILD)
                printf(" Error ECHILD!!\n");
            else if (errno == EINTR)
                printf(" Error EINTR!!\n");
            else
                printf("Error EINVAL!!\n");
        }
    }

    return 0;
}

【问题讨论】:

  • 任何一个都可以。你在某处做错了什么。如需进一步帮助,请发布您的代码并解释您所观察到的内容-
  • 也许你测试你是孩子还是父母的方法是错误的。向我们展示您的代码。
  • 查看errno 例如当 wait* 函数给出 -1 时使用 perror
  • 如果您得到 -1 返回值,请检查 errno,或使用 perror 打印错误消息。
  • 我将 ECHILD 设置为 errno。

标签: c linux fork wait waitpid


【解决方案1】:

正如我评论的:你的最后一个 else 应该是

 else perror("waitpid");

但是你得到的是ECHILD。所以请阅读waitpid(2) 手册页:

   ECHILD (for wait()) The calling process does not have any unwaited-
          for children.

  ECHILD (for waitpid() or waitid()) The process specified by pid
          (waitpid()) or idtype and id (waitid()) does not exist or is
          not a child of the calling process.  (This can happen for
          one's own child if the action for SIGCHLD is set to SIG_IGN.
          See also the Linux Notes section about threads.)

顺便说一句,我无法重现您的错误。还要检查ulimit -a 在 bash 上给出的限制。

也许你的execl 失败了(特别是如果你执行一些脚本而不是/bin/ls)。在其后添加对perror 的调用。

另外,使用gcc -Wall -g 编译并使用stracegdb

【讨论】:

  • 我在 printf 中使用了 strerror(errno)。我从 strerror 中获取字符串“No Child Process”(来自waitpid的-1返回值)。当 Child 运行时,我从 strerror 获取字符串“Succuss”,其中 0 作为 waitpid 的返回值。
猜你喜欢
  • 2017-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 2012-05-10
  • 2012-09-26
相关资源
最近更新 更多