sigaction函数
#include <signal.h>
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
类似于signal
函数,sigaction
可以为某些信号设置回调,这些设置都在struct sigaction
中进行
1.void (*sa_handler)(int)
信号处理函数
2.void (*sa_sigaction)(int,siginfo_t*,void*)
也是信号处理函数,当sa_flag
为SA_SIGFINFO
时将使用该函数
上述两个信号吹函数是互斥的,一次只能使用两个字段中的一个,因此在一些实现中,使用union
来存放这两个函数。 siginfo_t
结构体中存放了一些信号产生原因的有关信息。
3.sigset_t sa_mask
是一个sigset,可以在信号处理函数执行的时候屏蔽某些信号。
4.int sa_flags
这是一个选项字段。比如说:
SA_RESTART:使被信号打断的系统调用自动重新发起。
SA_NOCLDSTOP:使父进程在它的子进程暂停或继续运行时不会收到 SIGCHLD 信号。
SA_NOCLDWAIT:使父进程在它的子进程退出时不会收到 SIGCHLD 信号,这时子进程如果退出也不会成为僵尸进程。
下面例子说明sigaction
函数的部分用法:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
static void sig_usr(int signo)
{
printf("in signal handler\r\n");
sleep(20);//will not receive SIGINT
}
int main(int argc ,char **argv)
{
struct sigaction sa_usr;
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask,SIGINT);
sa_usr.sa_handler=sig_usr;
sa_usr.sa_mask=mask;
sa_usr.sa_flags=0;
sigaction(SIGUSR1,&sa_usr,NULL);
pause();
return 0;
}
另外,由于sigacation
提供了比signal
更多的功能,我们可以使用sigaction
来实现signal
函数
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <sys/time.h>
#include <malloc.h>
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t MySignal(int signo,sighandler_t handler)
{
struct sigaction act,oact;
sigset_t mask;
sigemptyset(&mask);
act.sa_handler=handler;
act.sa_mask=mask;
act.sa_flags |= SA_RESTART;
if(sigaction(signo,&act,&oact)<0)
return SIG_ERR;
return oact.sa_handler;
}
static void sig_handler(int signo)
{
printf("in sig handler\r\n");
}
int main(int argc, char **argv)
{
MySignal(SIGALRM,sig_handler);
alarm(5);
pause();
return 0;
}