我试图从父进程发送一个空白(SIGUSR1)信号。据我所知,我已正确设置信号。我觉得我搞乱了Kill()函数调用。我期待某种打印输出,但我什么都没得到。不是来自孩子内部,也不是来自信号功能本身。
代码:
void my_handler(int signum);
int main()
{
pid_t pid;
if((pid = fork()) == -1)
{
printf("Error on fork().\n");
exit(1);
}
if(pid == 0)
{
if(signal(SIGUSR1, my_handler))
{
printf("+1");
}
}
else if(pid > 0)
{
sleep(2);
kill(pid, SIGUSR1);
}
}
void my_handler(int signum)
{
if (signum == SIGUSR1)
{
printf("Received SIGUSR1!\n");
}
}
答案 0 :(得分:3)
子进程在父进程有机会向其发送信号之前退出。在致电sleep(5)
后,请尝试在子流程中添加signal
。
答案 1 :(得分:2)
您的孩子在发送信号之前退出:
if(pid == 0)
{
if(signal(SIGUSR1, my_handler))
{
printf("+1");
}
}
else if(pid > 0)
{
sleep(2);
kill(pid, SIGUSR1);
}
孩子可能会打印+1
,但随后会退出。同时,你的父母等了两秒钟,以确保孩子真的死了,然后给它发信号。它不存在!
要修复:添加某种代码,让孩子闲逛以接收信号。最简单的可能是pause();
,但sleep()
超过2秒就可以了。
您应该检查系统调用。例如:
if (kill(pid, SIGUSR1) != 0)
{
fprintf(stderr, "kill(%d) failed: %d %s\n", (int)pid, errno, strerror(errno));
exit(1);
}
您很快就厌倦了编写4行代码,因此您最终得到一个报告系统错误并退出的函数(使用C11 _Noreturn
):
void _Noreturn err_syserr(const char *fmt, ...)
{
int errnum = errno; // Capture it before it changes
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
if (errno != 0)
fprintf(stderr, "%d: %s\n", errnum, strerror(errnum));
exit(1);
}
使用:
if (kill(pid, SIGUSR1) != 0)
err_syserr("kill(%d) failed: ", (int)pid);
(并非所有人都同意打印错误编号;您付钱并接受选择。)
另请参阅How to avoid using printf
in a signal handler?这不是您问题的一部分,但您应该了解这些问题。