网络编程之 信号捕捉器(函数指针与回调函数)(2):https://developer.aliyun.com/article/1414738
sigaction()函数
前面我们讲到的内容已经足以用来防止僵尸进程生成的代码。之所以博主还要介绍sigaction()函数是因为它类似于signal()函数,而且完全可以代替后者,也更稳定(主要是书上介绍到了),之所有更稳定,是因为如下原因:
"signal()函数在UNIX系列的不同操作系统中可能存在区别,但sigaction()函数完全相同!"
实际上现在很少使用 signal()函数编写程序,它只是为了保持对旧程序的兼容(别崩溃啊)。下面介绍 sigaction()函数,单只脚接它的功能,展开来说太复杂了。
信号处理动作(通常在Linux用其来注册一个信号的捕捉函数) int sigaction(int signo, const struct sigaction *act, struct sigaction *oldact); 成功:0;失败:-1,设置errno 第一个参数 int signo: --->与signo相同,传递信号信息(我之前的博客写的很全) 第二个参数 const struct sigaction *act: --->传入参数,新的处理方式。 第三个参数 struct sigaction *oldact: --->传出参数,旧的处理方式。 返回值: 成功: 0 失败: -1,设置 errno
相信大家也看到了,上面有结构体
struct sigaction结构体(增加了书上没有的)
struct sigaction结构体 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_restorer:该元素是过时的,不应该使用,POSIX.1标准将不指定该元素。(弃用) sa_sigaction:当sa_flags被指定为SA_SIGINFO标志时,使用该信号处理程序。(很少使用) 重点掌握:(也就是我们书上的) sa_handler:指定信号捕捉后的处理函数名(即注册函数)。也可赋值为SIG_IGN表忽略 或 SIG_DFL表执行默认动作 sa_mask: 调用信号处理函数时,所要屏蔽的信号集合(信号屏蔽字)。注意:仅在处理函数被调用期间屏蔽生效,是临时性设置。(也可以设置为0) sa_flags:通常设置为0,表使用默认属性。
书上所说:
书上之所以让把 sa_mask也设置0里面有牵扯到了,
信号屏蔽字 与 未决信号集(博主也不展开说了,比较繁琐)
解决这个函数的难点吧。其实大家应该知道没有难点了。
第一个参数就是和signal的第一个参数一样
第二个参数的结构体我们只需要管三个参数就行而且:第二三个参数
sigset_t sa_mask;
int sa_flags;
都可直接设置0
所以结构体我们只用管第一个参数:
void (*sa_handler)(int);
这不就是我们的signal 得第二个参数吗?
第三个参数:直接传入之前的处理方式即可,如果不关心可以直接传NULL(传入之前的方式是为了恢复以前的处理方式)。
信号捕捉器讲完了========处理子进程回收的终极方法也将完了。下面看看书上的代码就可以结束我们这篇博客了
是不是好烦啊!!!sigempty()函数书上也没讲!!!
博主再来拓展一下(不要怪书上,谢了介绍的话又要增加大家的负担了,因为涉及信号集!)
信号集设定 sigset_t set; // typedef unsigned long sigset_t; int sigemptyset(sigset_t *set); 将某个信号集清0 成功:0;失败:-1 int sigfillset(sigset_t *set); 将某个信号集置1 成功:0;失败:-1 int sigaddset(sigset_t *set, int signum); 将某个信号加入信号集 成功:0;失败:-1 int sigdelset(sigset_t *set, int signum); 将某个信号清出信号集 成功:0;失败:-1 int sigismember(const sigset_t *set, int signum);判断某个信号是否在信号集中 返回值:在集合:1;不在:0;出错:-1 sigset_t类型的本质是位图(由 1 0 组成)。但不应该直接使用位操作,而应该使用上述函数,保证跨系统操作有效。
好啦博客结束了,细细看完这篇博客在看书上的内容应该不成问题了。
谢谢观看