1.我已经编写了一段示例代码,它将捕获SIGALRM信号退出主进程。
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/signal.h>
static int sig_flag=0;
static void mysignal(int sig)
{
sig_flag=1;
}
void installsignal(int sig,void( *signalhandler)(int))
{
struct sigaction action={0};
action.sa_handler=signalhandler;
action.sa_flags=0;
sigemptyset(&action.sa_mask);
if(sigaction(sig,&action,NULL)<0)
{
printf("can not catch signal signum:%d\n",sig);
}
}
main()
{
installsignal(SIGALRM,mysignal);
if(sig_flag==1)
{
printf("\n Signal has been caought\n");
exit(0);
}
while(1)
{
printf("\nHello world\n");
sleep(1);
}
exit(0);
}
2.当我改变我的程序时,如下所示它的工作原理: -
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/signal.h>
static int sig_flag=0;
static void mysignal(int sig)
{
sig_flag=1;
}
void installsignal(int sig,void( *signalhandler)(int))
{
struct sigaction action={0};
action.sa_handler=signalhandler;
action.sa_flags=0;
sigemptyset(&action.sa_mask);
if(sigaction(sig,&action,NULL)<0)
{
printf("can not catch signal signum:%d\n",sig);
}
}
main()
{
installsignal(SIGALRM,mysignal);
while(1)
{
printf("\nHello world\n");
if(sig_flag==1)
{
printf("\n Signal has been caought\n");
exit(0);
}
sleep(1);
}
exit(0);
}
为什么第一个示例代码无效?
答案 0 :(得分:4)
你的控制回路出错了。你永远不会要求里面的旗帜,所以你想要你注意到信号已被抓住了。
除了Basile是正确的,只使用sig_atomic_t
与信号处理程序进行通信。
答案 1 :(得分:3)
你应该定义
static volatile sig_atomic_t sig_flag=0;
了解volatile variables和sig_atomic_t并仔细阅读signal(7)
当然,您需要在循环中测试sig_flag
或使用pause(2)或sigsuspend(2)。也许您希望event loop使用poll(2)。阅读Advanced Linux Programming,time(7)以及特定于Linux的signalfd(2)和timerfd_create(2) ....