【问题标题】:What does signal(SIGCHLD, SIG_DFL); mean?什么信号(SIGCHLD,SIG_DFL);意思是?
【发布时间】:2023-04-01 04:29:01
【问题描述】:

我没有在我的代码中处理SIGCHLD。终止后我的进程仍然被立即删除。我希望它成为僵尸进程。

如果我将SIGCHLD 设置为SIG_DFL 那么它会起作用吗?如何将SIGCHLD 设置为SIG_DFL

我想让进程变成僵尸,所以我可以在waitpid之后读取父级中的子状态。

【问题讨论】:

  • 您应该始终使用waitpid 读取子状态,尤其是当您安装了SIGCHLD 处理程序(或没有它)时。阅读signal(7)signal(2)sigaction(2)了解详情。
  • waitpid 返回 -1 且 errno = ECHILD。所以子状态是无效的,只是一些垃圾。

标签: linux signals posix zombie-process waitpid


【解决方案1】:

从您的问题历史来看,您似乎对此束手无策。以下是其工作原理的概要:

  1. SIGCHLD 的默认处置是忽略。换句话说,如果你什么都不做,信号会被忽略,但僵尸进程表中存在。这就是为什么您可以在孩子死后随时wait

  2. 如果您设置了一个信号处理程序,那么信号就会被传递,您可以根据需要获取它,但是(前)孩子在它死亡和您获取它之间仍然是一个僵尸。

  3. 如果您手动通过signal 将 SIGCHLD 的处置设置为 SIG_IGN,则语义与第 1 项中的略有不同。当您手动设置此处置时,操作系统会立即删除当进程表中的子进程死亡并且创建一个僵尸时。因此,不再有任何状态信息可供获取,wait 将因 ECHILD 而失败。 (2.6.9 之后的 Linux 内核遵循此行为。)

【讨论】:

    【解决方案2】:

    所以你的最终目标是在子进程退出后读取父进程中的返回码?我不认为这与信号有任何关系。一些示例代码是:

    short pid;
    if((pid == fork()) == 0) {
    // Child process do some thing here.
    exit(n);
    } else {
      int returnCode;
      while(pid != wait(&returnCode));
      // the child has terminated with returnCode
      // wait is blocking system call so u don't need to worry about busy waiting.
    }
    

    【讨论】:

    • 是的,在这里我总是从等待中得到-1(返回值)。我期望从等待中获得子 pid 作为返回值。所以我可以继续孩子的身份。在我的情况下没有发生这种情况。当我检查 errno 时,它是 ECHILD。那么如何检查 SIGCHLD 标志呢?
    • 查看link 将信号与处理程序绑定,看看发生了什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    • 2011-11-30
    • 2014-05-11
    相关资源
    最近更新 更多