这个很详细。如果你有耐心看的话,很不错。
struct
sigaction
#ifdef __USE_POSIX199309
# define sa_handler __sigaction_handler.sa_handler
# define
sa_sigaction
#else
#endif
在网上查了一些书料这个结构大概是这样的
其中,sa_restorer,已过时,POSIX不支持它,不应再被使用。
1、联合数据结构中的两个元素_sa_handler以及*_sa_sigaction指定信号关联函数,即用户指定的信号处理函数。除了可以是用户自定义的处理函数外,还可以为SIG_DFL(采用缺省的处理方式),也可以为SIG_IGN(忽略信号)。
2、由_sa_handler指定的处理函数只有一个参数,即信号值,所以信号不能传递除信号值之外的任何信息;由_sa_sigaction是指定的信号处理函数带有三个参数,是为实时信号而设的(当然同样支持非实时信号),它指定一个3参数信号处理函数。第一个参数为信号值,第三个参数没有使用(posix没有规范使用该参数的标准),第二个参数是指向siginfo_t结构的指针,结构中包含信号携带的数据值,参数所指向的结构如下:
在/usr/include/bits/siginfo.h中是这样定义的
typedef struct siginfo
{
} siginfo_t;
是不是太复杂了,在网上有一个简洁版我搬过来用一下
siginfo_t {
union{
//确保分配足够大的存储空间
int _pad[SI_PAD_SIZE];
//对SIGKILL有意义的结构
struct{
...
... ...
... ...
//对SIGILL, SIGFPE, SIGSEGV, SIGBUS有意义的结构
...
... ...
}
3、sa_mask指定在信号处理程序执行过程中,哪些信号应当被阻塞。缺省情况下当前信号本身被阻塞,防止信号的嵌套发送,除非指定SA_NODEFER或者SA_NOMASK标志位。
注:请注意sa_mask指定的信号阻塞的前提条件,是在由sigaction()安装信号的处理函数执行过程中由sa_mask指定的信号才被阻塞。
4、sa_flags中包含了许多标志位,包括刚刚提到的SA_NODEFER及SA_NOMASK标志位。另一个比较重要的标志位是SA_SIGINFO,当设定了该标志位时,表示信号附带的参数可以被传递到信号处理函数中,因此,应该为sigaction结构中的sa_sigaction指定处理函数,而不应该为sa_handler指定信号处理函数,否则,设置该标志变得毫无意义。即使为sa_sigaction指定了信号处理函数,如果不设置SA_SIGINFO,信号处理函数同样不能得到信号传递过来的数据,在信号处理函数中对这些信息的访问都将导致段错误(Segmentation fault)。
注:很多文献在阐述该标志位时都认为,如果设置了该标志位,就必须定义三参数信号处理函数。实际不是这样的,验证方法很简单:自己实现一个单一参数信号处理函数,并在程序中设置该标志位,可以察看程序的运行结果。实际上,可以把该标志位看成信号是否传递参数的开关,如果设置该位,则传递参数;否则,不传递参数。
结构说的也差不多了,其实在我看到这些东西的时候给弄晕了好几回,简单的说几句就是
如果要在某信号产生时触发某些动作我们就可以安装信号
signal
用于安装不可靠信号
sigaction 用于安装可靠信号 当然他也可以安装不可靠信号 并且可以附带更多的信息
signal安装信号时只需传入2个参数
一个是信号的值
sigaction 安装时有3个参数 第一个参数是信号的值,第二个是sigaction结构
这个结构说明了信号发生时调用的函数和其它的一些信息,主要的成员是 sa_handler 指定的触发函数只带一个参数即信号的值
这和signal调用没什么区别,sa_sigaction指定的触发函数带有3个参数
第一个参数是信号的值,第二个参数是包函附加信息的结构siginfo,第三个参数为空
如果要传递附加信息给触发函数那么必须将传给sigaction的第二个参数sigaction结构的sa_flag设为SA_SIGINFO
上面说了那么多结构体和复杂的很的siginfo,其实siginfo我们在实际应用中并不需要去初始化他或者做什么,只是在信号触发时我们可以从这个结构体中提取一些信息
说了这么多我们可以小试牛刀了
自己写一个程序
[root@localhost clang]# cat f4.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
void test(int
n,struct siginfo *siginfo,void *myact)
{
}
int main(void)
{
}
[root@localhost clang]#
[root@localhost clang]# ./test
wait for the signal
wait for the signal
wait for the signal
wait for the signal
signal number:2
siginfo signo:2
siginfo errno:0
siginfo co
wait for the signal
wait for the signal
wait for the signal
signal number:2
siginfo signo:2
siginfo errno:0
siginfo co
wait for the signal
[2]+
[root@localhost clang]# kill %1
[1]-
[root@localhost clang]#
可以看到当按下CTRL+C结束程序时信号将触发执行test函数
本文详细解析了sigaction结构体的各个字段含义及其应用场景,通过对比signal函数,突出了sigaction在信号处理上的优势,最后通过一个示例程序展示了如何使用sigaction安装信号处理函数。

被折叠的 条评论
为什么被折叠?



