sigaction和signal一样用来注册信号处理函数,siqqueue和kill一样,用来发送信号,但是sigaction比signal功能强大,signal比较简单。
int sigaction(int signum, const struct sigaction *act, struct sigaction* oldact /*保存老的sigaction*/);
struct sigaciton{
void (*sa_handler)(int); // 回调函数
void (*sa_sigaction)(int, siginfo_t*, void*); // 回调函数
sigset_t sa_mask; // 在信号出发执行回调函数的期间,屏蔽sa_mask所指定的信号
int sa_flags; // 为0表示默认行为,设置为SA_RESTART时,被信号打断后,系统调用可以重启
void (*sa_restorer)(void); // should not to be use
};
void sig_handle(int val, siginfo_t* info, void* p)
{
printf("sig_handle\n");
}
int main()
{
struct sigaction act;
act.sa_handler = NULL;
act.sa_sigaction = sig_handle;
act.sa_flags = SA_RESTART;
sigemptyset(&act.sa_mask);
act.sa_restorer = NULL;
sigaction(SIGINT, &act, NULL);
while (1)
{
sleep(1);
}
return 0;
}
int sigqueue(pid_t pid, int sig, const union sigval value);
union sigval{
int sigval_int;
void *sigval_ptr;
}
void sig_handle(int val, siginfo_t* info, void* p)
{
printf("sig_handle value = %d\n", info->si_int);
}
int main()
{
struct sigaction act;
act.sa_handler = NULL;
act.sa_sigaction = sig_handle;
act.sa_flags = SA_SIGINFO; // 如果sigqueue要传参数给信号处理函数,这个要设置为SA_SIGINFO;
sigemptyset(&act.sa_mask);
act.sa_restorer = NULL;
sigaction(SIGINT, &act, NULL);
pid_t pid = fork();
if (pid == 0)
{
union sigval v;
v.sival_int = 100;
sigqueue(getppid(), SIGINT, v);
return 0;
}
while (1)
{
sleep(1);
}
wait(NULL);
return 0;
}
强大:
-
可以传递参数
-
可以获得发送信号的进程信息
-
可以设置SA_RESTART
> SA_RESTART:
void handle(int v, siginfo_t* v1, void* v2)
{
printf("sig handle\n");
}
int main()
{
// signal(SIGINT, handle);
struct sigaction act;
act.sa_handler = NULL;
act.sa_sigaction = handle;
sigemptyset(&act.sa_mask);
// 设置了restart之后,如果该信号打断了某个系统阻塞调用时,该系统调用会自动重启
// act.sa_flags = SA_RESTART;
act.sa_flags = 0; // 被打断的系统调用不会重启
act.sa_restorer = NULL;
sigaction(SIGINT, &act, NULL); // signal 默认打断了可以重启
char buf[1024];
int ret;
READAGAIN:
ret = read(0, buf, sizeof(buf));
// 阻塞的read被中断打断时,会返回-1
if(ret < 0)
{
if(errno == EINTR)
{
printf("read is interrupt by signal\n");
goto READAGAIN;
}
}
buf[ret] = 0;
printf("%s\n", buf);
}