gpt4 book ai didi

无法接收到所有的 SIGCHLD

转载 作者:太空狗 更新时间:2023-10-29 12:23:49 27 4
gpt4 key购买 nike

在下面的代码中,我期望的是控制台打印十个 SIGCHLD caught。我已经通过将 sa_flags 设置为 SA_SIGINFO 并使用 sa_sigaction 而不是 sa_handler 来排队 SIGCHLD。但是,似乎有些 SIGCHLD 丢失了。为什么?

我在想 fork() 可能会被 SIGCHLD 打断,所以我使用 SA_RESTART 重新启动 fork()。我在不同的计算机上运行同一段代码。在我的 MacBook 上,它显示 [1] 24481 illegal hardware instruction。在另一台 Linux 计算机上,打印了不到 10 个 SIGCHLD caught

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h>

#define CHECK(syscall, msg) do { \
if ((syscall) == -1) { \
perror(msg); \
} \
} while(0)

void catch(int signo, siginfo_t *info, void *context) {
if (signo == SIGCHLD) {
printf("SIGCHLD caught\n");
}
}

int main () {
sigset_t new_set;
sigemptyset(&new_set);
sigaddset(&new_set, SIGCHLD);
struct sigaction act;
act.sa_sigaction = catch;
act.sa_mask = new_set;
act.sa_flags = SA_SIGINFO | SA_RESTART;
CHECK(sigaction(SIGCHLD, &act, NULL), "sigaction error");

int pid, i;
for (i = 0; i < 10; i++) {
pid = fork();
if (!pid) return;
}
while (1);
}

最佳答案

SIGCHLD 是一个标准信号,这意味着它的多次出现会合并为一个。 Linux 内核为标准信号维护一个位集,每个信号一位,并支持恰好排队一个关联的 siginfo_t

修复:

void catch(int signo, siginfo_t*, void*) {
int status;
pid_t pid;
if(signo == SIGCHLD) {
while((pid = waitpid(-1, &status, WNOHANG)) > 0)
printf("child %u terminated.\n", (unsigned)pid);
}
}

另请注意,您不需要显式阻止您处理的信号,因为它会自动为您阻止,除非使用 SA_NODEFER 标志。

而且,迂腐地,只有有限数量的异步信号安全函数(参见 man signal-safety )可以用在信号处理程序中,printf 不是其中之一。

关于无法接收到所有的 SIGCHLD,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48750382/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com