10 信号
#include
#include
int kill(pid_t pid, int sig);
pid>0
pid=0//信号发送给本进程组内的其他进程
pid=-1//发送给除init之外的所有进程,但发送者要拥有对目标进程发送信号的权限
pid<-1//信号发送给组ID为-pid的进程组中的所有成员
将sig设置为0可以用来检测目标进程或进程组是否存在。但是这种检测不可靠,一方面由于进程PID的回绕,可能导致PID不是我们期望的PID;另一方面,这种检测方法不是原子操作。
#include
typedef void (*__sighandler_t)(int);
在bits/signum.h头文件中还定义了信号的两种其他处理方式--SIG_IGN和SIG_DFL:
#include
#define SIG_DFL ((__sighandler_t) 0)
#define SIG_IGN ((__sighandler_t) 1)
#include
_sighandler_t signal(int sig, _sighandler_t _handler);
int sigaction(int sig, const struct sigaction* act, struct sigaction* oact);
struct sigaction{
#ifdef __USE_POSIX199309
union{
_sighandler_t sa_handler;
void (*sa_sigaction)(int, siginfo_t*, void*);
}_sigaction_handler;
#define sa_handler __sigaction_handler.sa_handler
#define sa_sigaction __sigaction_handler.sa_sigaction
#else
_sighandler_t sa_handler;
#endif
_sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
信号集:
#include
#define _SIGSET_NWORDS (1024/(8*sizeof(unsigned long int)))
typedef struct{
unsigned long int __val[_SIGSET_NWORDS];
}__sigset_t;
由定义可见,sigset_t实际上是一个长整型数组,数组的每个元素的每个位表示一个信号。这种定义方式和文件描述符集fd_set类似。Linux提供了如下一组函数来设置、修改、删除和查询信号集:
#include
int sigempty(sigset_t* set);
int sigfillset(sigset_t* set);
int sigaddset(sigset_t* _set, int _signo);
int sigdelset(sigset_t* _set, int _signo);
int sigismember(_const sigset_t* _set, int _signo);
进程信号掩码
可以利用sigaction结构体的sa_mask成员来设置进程的信号掩码。此外,如下函数也可以用于设置或查看进程的信号掩码:
#include
int sigprocmask(int _how, _const sigset_t* _set, sigset_t* _oset);
_how可以设置为:
SIG_BLOCK;
SIG_UNBLOCK;
SIG_SETMASK;
如果_set为NULL,则进程信号掩码不变,此时我们仍然可以利用_oset参数来获得进程当前的信号掩码。
设置进程信号掩码后,被屏蔽的信号将不可能被进程接收。如果给进程发送一个被屏蔽的信号,则操作系统将该信号设置为进程的一个被挂起的信号。如果我们取消对被挂起信号的屏蔽,则它能立即被进程接收到。获得进程当前被挂起的信号集:
#include
int sigpending(sigset_t* set);
fork调用产生的子进程将继承父进程的信号掩码,但是具有一个空的挂起信号集。
统一事件源:
把信号的主要处理逻辑放在程序的主循环中,当信号处理函数被触发时,它只是简单的通知主循环接收到信号,并把信号值传递给主循环,主循环在根据接收到的信号值执行目标信号对应的逻辑代码。信号处理函数通常使用管道将信号“传递”给主循环:信号处理函数往管道写入信号值,主循环从管道读出信号值。主程序使用IO多路复用来监听管道的读端文件描述符上的可读事件。如此一来,信号事件就能够和其他IO时间一样被处理,即统一事件源。如Libevent IO框架库和xinetd超级服务。
阅读(1841) | 评论(0) | 转发(0) |