信号集类型sigset_t
定义
typedef struct
{
unsigned long sig[_NSIG_WORDS];
} sigset_t
相关函数
sigemptyset(sigset_t *set) //初始化由set指定的信号集,信号集里面的所有信号被清空
sigfillset(sigset_t *set) //调用该函数后,set指向的信号集中将包含linux支持的64种信号
sigaddset(sigset_t *set, int signum) //在set指向的信号集中加入signum信号;
sigdelset(sigset_t *set, int signum) //在set指向的信号集中删除signum信号;
sigismember(const sigset_t *set, int signum) //判定信号signum是否在set指向的信号集中。
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_handler
:函数指针,指向信号处理函数。默认使用此函数处理信号sa_sigaction
:同样是信号处理函数,有三个参数,可以获得关于信号更详细的信息。可以通过参数三使用此函数处理信号。即参数一和参数二是二选一的。sa_mask
:信号处理函数执行期间需要被屏蔽的信号sa_flags
:指定信号处理的行为- SA_RESTART,使被信号打断的系统调用自动重新发起
- SA_NOCLDSTOP,使父进程在它的子进程暂停或继续运行时不会收到 SIGCHLD 信号
- SA_NOCLDWAIT,使父进程在它的子进程退出时不会收到 SIGCHLD 信号,这时子进程如果退出也不会成为僵尸进程
- SA_NODEFER,使对信号的屏蔽无效,即在信号处理函数执行期间仍能发出这个信号
- SA_RESETHAND,信号处理之后重新设置为默认的处理方式
- SA_SIGINFO,使用
sa_sigaction
而不是sa_handler
作为信号处理函数
sa_restorer
:废弃不使用
Linux下信号处理机制
Linux下的信号采用的异步处理机制,当进程收到信号时,操作系统会中断进程当前的正常流程,转而进入信号处理函数执行操作,完成后再返回中断的地方继续执行,且信号处理期间系统不会再次触发它,即处理期间如果有同类型的信号发来会被屏蔽。所以我们希望信号处理函数执行快、尽可能少错过信号。
一般的解决方案是,信号处理函数用于通知主循环发生信号,具体的处理逻辑放在主循环中。
统一事件源
信号处理函数使用管道将信号传递给主循环,信号处理函数往管道的写端写入信号值,主循环则从管道的读端读出信号值,使用I/O复用(select、poll、epoll)系统调用来监听管道读端的可读事件,这样信号事件与其他文件描述符都可以通过epoll来监测,从而实现统一处理。
使用管道通信
在linux下,使用socketpair函数能够创建一对套接字进行通信
#include <sys/types.h>
#include <sys/socket.h>
int socketpair(int domain, int type, int protocol, int sv[2]);
domain
:协议族type
:协议。SOCK_STREAM(基于TCP)或者SOCK_DGRAM(基于UDP)protocol
:类型,只能为0sv[2]
:即管道两端,均可进行读写操作- 返回值:成功为0,失败为-1