我正在编写一个 Unix 程序,其中一个父进程派生一个子进程,稍后它必须发送一个 SIGUSR1 信号由 handler_sigusr1 处理,并发送一个 SIGKILL 信号来完成该程序。 我的问题是,当我运行该程序时,子程序应该收到 SIGUSR1,然后收到 SIGKILL,但它只收到 SIGKILL。 我的代码有问题吗?感谢您的帮助!
void handler_sigusr1()
{
printf("Signal SIGUSR1\n");
}
int main(int argc, char **argv)
{
struct sigaction action;
sigset_t new_mask, oldmask;
int status;
action.sa_flags = 0;
sigaction(SIGTERM, &action, NULL);
sigemptyset(&new_mask);
sigaddset(&new_mask, SIGTERM);
sigaction(SIGUSR1, &action, NULL);
action.sa_handler = handler_sigusr1;
sigaddset(&new_mask, SIGUSR1);
child1 = fork();
if(child1 == 0)
{
sigprocmask(SIG_BLOCK, &new_mask, &oldmask);
sigsuspend(&new_mask);
}
if(child1 != 0)
{
kill(child1, SIGUSR1);
kill(child1, SIGKILL);
}
wait(&status);
}
最佳答案
有4个问题:
问题 1
设置信号处理程序的代码是错误的。
这两行顺序错误:
sigaction(SIGUSR1, &action, NULL);
action.sa_handler = handler_sigusr1;
应该是
action.sa_handler = handler_sigusr1;
sigaction(SIGUSR1, &action, NULL);
第 2 期
您的父进程在发送 SIGUSR1 后立即向您的子进程发送 SIGKILL。 SIGKILL 将终止您的子进程 - 它不能被阻止或忽略。
除非你很幸运,否则你的 child 的 sigusr1 处理程序将无法在父进程发送 SIGKILL 之前运行或完成 - 这会立即终止子进程。
您可以通过像这样插入延迟来大大增加 SIGUSR1 被传递和处理的机会:
kill(child1, SIGUSR1);
sleep(1);
kill(child1, SIGKILL);
问题 3
您已阻止 SIGUSR1,因此它不会传送到您的进程。
删除行
sigaddset(&new_mask, SIGUSR1);
请注意,当使用 sigprocmask()
或 sigsuspend()
设置信号掩码时,掩码中设置的信号是被阻塞的信号.
第四期
您不能在信号处理程序中安全地使用 printf()。
printf() 不是信号异步安全的,不能在信号处理程序中使用。如果你不走运,它可能不会像在信号处理程序中使用时那样表现。使用 write() 而不是直接写入标准输出,例如
write(1, "Signal SIGUSR1\n", 15);
关于c - 为什么不处理 SIGUSR1 信号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40984985/