sigaction的用法
int sigaction (
int signo,
const struct sigaction *act,
struct sigaction *oldact
);
这个函数主要是用于改变或检测信号的行为。
第一个参数是变更signo指定的信号,它可以指向任何值,SIGKILL,SIGSTOP除外
第二个参数,第三个参数是对信号进行细粒度的控制。
如果*act不为空,*oldact不为空,那么oldact将会存储信号以前的行为。
如果act为空,*oldact不为空,那么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);
}
参数含义:
sa_handler是一个函数指针,主要是表示接收到信号时所要采取的行动。此字段的值可以是SIG_DFL,SIG_IGN.分别代表默认操作与内核将忽略进程的信号。这个函数只传递一个参数那就是信号代码。
当SA_SIGINFO被设定在sa_flags中,那么则会使用sa_sigaction来指示信号处理函数,而非sa_handler.
sa_mask设置了掩码集,在程序执行期间会阻挡掩码集中的信号。
sa_flags设置了一些标志, SA_RESETHAND当该函数处理完成之后,设定为为系统默认的处理模式。SA_NODEFER 在处理函数中,如果再次到达此信号时,将不会阻塞。默认情况下,同一信号两次到达时,如果此时处于信号处理程序中,那么此信号将会阻塞。
SA_SIGINFO表示用sa_sigaction指示的函数。
sa_restorer已经被废弃。
sa_sigaction所指向的函数原型:
void my_handler(int signo, siginfo_t *si, void *ucontext);
第一个参数: 信号编号
第二个参数:指向一个siginfo_t结构。
第三个参数是一个ucontext_t结构。
其中siginfo_t结构体中包含了大量的信号携带信息,可以看出,这个函数比sa_handler要强大,因为前者只能传递一个信号代码,而后者可以传递siginfo_t信息。
typedef struct siginfo_t {
int si_signo;//信号编号
int si_errno;//如果为非零值则错误代码与之关联
int si_code;//说明进程如何接收信号以及从何处收到
pid_t si_pid;//适用于SIGCHLD,代表被终止进程的PID
pid_t si_uid;//适用于SIGCHLD,代表被终止进程所拥有进程的UID
int si_status;//适用于SIGCHLD,代表被终止进程的状态
clock_t si_utime;//适用于SIGCHLD,代表被终止进程所消耗的用户时间
clock_t si_stime;//适用于SIGCHLD,代表被终止进程所消耗系统的时间
sigval_t si_value;
int si_int;
void * si_ptr;
void* si_addr;
int si_band;
int si_fd;
};
sigqueue的用法
sigqueue( pid_t pid, int signo, const union sigval value)
union sigval {int sival_int, void*sival_ptr };
sigqueue函数类似于kill,也是一个进程向另外一个进程发送信号的。
但它比kill函数强大。
第一个参数指定目标进程的pid.
第二个参数是一个信号代码。
第三个参数是一个共用体,每次只能使用一个,用来进程发送信号传递的数据。
或者传递整形数据,或者是传递指针。
发送的数据被sa_sigaction所指示的函数的siginfo_t结构体中的si_ptr或者是si_int所接收。
sigpending的用法
sigpending(sigset_t set);
这个函数的作用是返回未决的信号到信号集set中。
即未决信号集,未决信号集不仅包括被阻塞的信号,也可能包括已经到达但没有被处理的信号。
示例1: sigaction函数的用法
void signal_set1(int x) { //信号处理函数,只传递一个参数信号代码
printf("xxxxx/n");
while(1) {
//
}
}
void signal_set(struct sigaction *act)
{
switch(act->sa_flags) {
case (int)SIG_DFL:
printf("using default hander/n");
break;
case (int)SIG_IGN:
printf("ignore the signal/n");
break;
default:
printf("%0x/n",act->sa_handler);
}
}
int main(int argc, char** argv)
{
int i;
struct sigaction act,oldact;
act.sa_handler = signal_set1;
act.sa_flags = SA_RESETHAND;
//SA_RESETHANDD 在处理完信号之后,将信号恢复成默认处理
//SA_NODEFER在信号处理程序执行期间仍然可以接收信号
sigaction (SIGINT,&act,&oldact) ;//改变信号的处理模式
for (i=1; i