【问题标题】:what is the relation between SIGTSTP and SIGCHLDSIGTSTP 和 SIGCHLD 之间的关系是什么
【发布时间】:2013-11-09 21:48:26
【问题描述】:

我对它们中的每一个都有两个处理程序(SIGTSTP、SIGCHLD),问题是当我使用 SIGTSTP 暂停进程时,SIGCHLD 的处理程序函数也会运行。我应该怎么做才能防止这种情况发生。

信号处理程序:

void signalHandler(int signal) {
int pid, cstatus;
if (signal == SIGCHLD) {
    susp = 0;
    pid = waitpid(-1, &cstatus, WNOHANG);
    printf("[[child %d terminated]]\n", pid);
    DelPID(&JobsList, pid);
}
}

void ctrlZsignal(int signal){
    kill(Susp_Bg_Pid, SIGTSTP);
    susp = 0;
    printf("\nchild %d suspended\n", Susp_Bg_Pid);
}

Susp_Bg_Pid 用来保存暂停的进程id。
susp 表示父进程是否被挂起时“粉碎”的状态。

【问题讨论】:

  • 看来,使用正确的标志,您可以知道哪个孩子暂停了,以及它收到了哪个信号。因此,这不仅可以让您检测到实际退出,还可以对暂停/恢复采取一些措施。

标签: c linux signals posix sigchld


【解决方案1】:

使用sigactionSA_NOCLDSTOP 设置您的SIGCHLD 处理程序。

来自sigaction (2)

SA_NOCLDSTOP - 如果 signum 是 SIGCHLD,当子进程停止(即,当它们接收到 SIGSTOP、SIGTSTP、SIGTTIN 或 SIGTTOU 之一时)或恢复(即,它们接收到 SIGCONT)时,不会收到通知(参见 wait(2)) .该标志仅在为 SIGCHLD 建立处理程序时才有意义。

更新

void signalHandler(int sig)
{
  //...
}

struct sigaction act;

act.sa_handler = signalHandler;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_NOCLDSTOP;

if (sigaction(SIGCHLD, &act, 0) == -1)
{
  perror("sigaction");
  exit(1);
}

如果您不熟悉 sigaction,您应该阅读它,因为它有几个不同的选项和行为,它们远远优于 signal,但在您弄清楚如何使用之前会以复杂性和混乱为代价用它。我对您似乎想要做什么做出了最好的猜测,但您需要尽早了解这一点。

【讨论】:

  • 顺便说一句,虽然 SA_NOCLDSTOP 在 *nix 平台上可用,但它依赖于实现,可能无法在所有平台上按预期工作。它适用于 linux。
猜你喜欢
  • 2021-01-04
  • 2012-01-30
  • 2012-08-12
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 2018-06-13
  • 2016-10-03
  • 1970-01-01
相关资源
最近更新 更多