信号处理
1 linux系统中对信号的处理主要由signal和sigaction函数来完成
Signal函数用来设置进程在接收到信号时的动作
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum,sighandler_t handler);
signal会根据参数signum指定的信号编号来设置该信号的处理函数。当指定的信号到达时就会跳转到参数handler指定的函数执行。如果参数handler不是函数指针,最必须是常数SIG_IGN(忽略该信号)或者SIG_DFL(对该信号执行默认操作)。
signal函数执行成功时返回以前的信号处理函数指针,当有错误发生时返回SIG_ERR(-1)
int sigaction(int signum,const struct sigaction *act, struct sigaction *oldact);
2 信号处理函数的返回
setjmp/longjmp 使用longjmp可以跳转到setjmp设置的位置
#include <setjmp.h>
int setjmp(jmp_buf env);
void longjmp(jmp_buf env,int val);
sigsetjmp/siglongjmp 和setjmp/longjmp的区别在于sigsetjmp在env中保存进程的当前信号屏蔽字,在调用siglongjmp时从其中恢复保存的信号屏蔽字
3 信号的发送
Kill函数用来发送信号给指定的进程
#include <sys/types.h>
#include <signal.h>
Int kill(pid_t pid,int sig);
raise函数 : int raise(int sig); 给调用自己的进程发送信号
sigqueue函数: 支持信号带有参数
alarm函数 : 可以设置定时器,定时器超时将产生SIGALRM信号给调用进程
int alarm(unsigned int seconds);
getitimer/setitimer函数
abort函数
4 pause 函数使调用进程挂起直至捕捉到一个信号。
Int pause(void);
Pause函数会令当前的进程暂停(进入睡眠),直到被信号中断
5 信号集
int sigemptyset(sigset_t *set); 初始化一个信号集,不包括任何信号
int sigfillset(sigset_t *set); 初始化一个信号集,包含所有信号
int sigaddset(sigset_t *set,int signum); 向set指定的信号集中添加signum信号
int sigdelset(sigset_t *set, int signum);从set指定的信号集中删除signum信号
int sigismember(const sigset_t *set,int signum);测试信号signum是否包括在set指定的信号集中
6 信号屏蔽
int sigprocmask(int how,const sigset_t *set,sigset_t *oldset);
int sigpending(sigset_t *set);
int sigsuspend(const sigset_t *mask);
sigsuspend将进程的信号屏蔽码设置为mask,然后和pause函数一样等待信号的发生并执行信号处理函数。信号处理函数执行完后再把进程的信号屏蔽码设置为原来的屏蔽字,然后sigsuspend函数才返回。Sigsuspend函数保证改变进程的屏蔽码和讲进程挂起等到信号是原子操作。