Linux信号透彻分析理解与各种实例讲解( 三 )


参数how决定了操作的方式:
SIG_BLOCK 增加一个信号集合到当前进程的阻塞集合中去
SIG_UNBLOCK 从当前的阻塞集合中删除一个信号集合
SIG_SETMASK 将当前的信号集合设置为信号阻塞集合
下面看一个例子:
#includeint sigaction(int signo,const struct sigaction *act,struct sigaction *oldact); 执行结果:
SIGINT singal blockedblock 0block 1block 2block 3block 4block 5block 6block 7block 8block 9在执行到block 3时按下了CTRL+C并不会终止 , 直到执行到block9后将集合从阻塞集合中移除 。 [root@localhost C]# ./s1SIGINT singal blockedblock 0block 1block 2block 3block 4block 5block 6block 7block 8block 9SIGINT SINGAL unblokcedunblock 0unblock 1由于此时已经解除了阻塞 , 在unblock1后按下CTRL+C则立即终止 。
2. 信号处理函数
struct sigaction {void (*sa_handler)(int);void (*sa_sigaction)(int,siginfo_t*,void*);sigset_t sa_mask;int sa_flags;void (*sa_restorer)(void);} 这个函数主要是用于改变或检测信号的行为 。
第一个参数是变更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 , 代表被终止进程的PIDpid_t si_uid;//适用于SIGCHLD,代表被终止进程所拥有进程的UIDint 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(pid_t pid,int signo,const union sigval value)union sigval{int sival_int, void*sival_ptr};