【问题标题】:How to do something in C when a process terminates without hanging the program?当进程终止而不挂起程序时,如何在 C 中做某事?
【发布时间】:2021-02-14 12:36:02
【问题描述】:

目前,我正在学习 UNIX 系统上的进程。

我的问题是,每次后台进程终止时我都需要做一些事情。这意味着我不能使用 waitpid 的典型功能,因为这样该进程就不会在后台运行,它会挂起程序。

我也知道每当父进程的子进程终止时都会发送 SIGCHLD 信号,但是我不知道如何获取我需要的所述进程的进程 ID。

在 C 中解决这个问题的正确方法是什么?我已经尝试过诸如 waitpid 上的 WNOHANG 选项之类的方法,但是它当然只会被调用一次,所以我不知道如何将其应用于我目前的情况。

【问题讨论】:

  • 我相信您可以在信号处理程序中发出wait 调用。虽然没有必要,但您可以在那里使用WNOHANG 进行waitpid。请参阅man signal-safety 以获取您可以在处理程序中安全地执行的调用列表。如果您需要进行非安全调用,这取决于您的基本级别循环是如何设计的[或等待]处理程序将任何必要的数据发送回基本级别。
  • 是的!这就是解决方案。作为参考,至少在我的情况下,使用 sigaction 是多余的,因为我需要做的就是检查被终止的进程是否在列表中。只需在 sigchld 处理函数中使用 wait() 即可!我的困惑在于不明白 wait() 和 waitpid() 函数有多么相似,由于某种原因它使我无法理解 wait() 本身并没有返回已终止进程的 pid。谢谢!

标签: c shell unix


【解决方案1】:

waitpid,因为这样进程就不会在后台运行,它会挂起程序。

如果进程不会在后台运行,waitpid 带有 pid 参数 将立即退出(假设没有 pid 冲突)。不过,这不是真的 - 只需使用 WNOHANG...

但是我不知道如何获取我需要的上述进程的进程 ID。在 C 中解决这个问题的正确方法是什么?

使用sigaction 注册信号处理程序并使用siginfo_t 类型的第二个信号处理程序参数中的字段si_pid。来自man sigaction

SIGCHLD填写si_pid、si_uid、si_status、si_utime、si_stime, 提供有关孩子的信息。 si_pid 字段是 子进程ID

使用它的工作示例位于man 3p wait 页面的Waiting for a Child Process in a Signal Handler for SIGCHLD 部分下。

在 C 中解决这个问题的正确方法是什么?

C 标准不知道子进程和 SIGCHLD 信号。这些是您的操作系统的一部分。在这种情况下,行为由POSIX 标准化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-29
    • 1970-01-01
    • 1970-01-01
    • 2017-03-27
    • 1970-01-01
    • 1970-01-01
    • 2016-09-15
    相关资源
    最近更新 更多