现在的位置: 首页 > 综合 > 正文

使用sigaction实现signal

2013年11月29日 ⁄ 综合 ⁄ 共 1773字 ⁄ 字号 评论关闭

来源:http://www.fengyj.net/blog/?p=434

 

由于历史原因,signal在各种平台上的实现可能会不尽相同,而POSIX明确规定调用sigaction函数的语义,但sigaction函数调用往往比较复杂,解决方法是用sigaction实现自己的signal函数,signal函数原型:

1.void (*signal(int signo, void (*handle)(int)))(int);

其中signal接受两个参数,一个int型的信号编码,另一个处理信号的函数指针,然后返回一个之前定义的处理信号的函数的指针,处理函数接受一个int型参数,返回void,这样看起来挺麻烦的,简单点可以这样定义:

1.typdef void (SIG_HANDLE)(int);
2.SIG_HANDLE *signal(int, SIG_HANDLE *);

好了,知道了signal的基本语义了,现在可以用sigaction实现它了,代码如下:

01.#include <signal.h>
02.  
03./*
04.* 用sigaction实现signal
05.*/
06.  
07.typedef void (SIG_PROC)(int);
08.  
09.SIG_PROC *_signal(int signo, SIG_PROC *sig_proc)
10.{
11.struct sigaction act;
12.struct sigaction oact;
13.  
14.act.sa_handler = sig_proc;
15.// 设置信号处理函数的信号掩码:信号处理函数调用期间,除屏蔽本信号外,不阻塞其他信号,信号处理函数执行完毕后,信号屏蔽字恢复到之前的值
16.sigemptyset(&act.sa_mask);
17.act.sa_flags = 0;
18.  
19.// 除了SIGALRM以外的其他信号,如果被中断都将尝试重新启动(linux下)
20.if (signo == SIGALRM)
21.{
22.#ifdef SA_INTERRUPT
23.act.sa_flags |= SA_INTERRUPT;
24.#endif
25.}
26.else
27.{
28.#ifdef SA_RESTART
29.//如果设置了restart,内核将重启被中断的系统调用,系统调用不会返回-1
30.act.sa_flags |= SA_RESTART;
31.#endif
32.}
33.  
34.if (sigaction(signo, &act, &oact) < 0)
35.{
36.return SIG_ERR;
37.}
38.return oact.sa_handler;
39.}

顺便说一下,信号一般由其他进程或内核发送给进程,对信号的处理有3种方式,分别为自己定义信号处理函数、忽略该信号和采用默认的方式:

  • 自定义信号处理函数:SIGKILL和SIGSTOP不能被捕获
  • 忽略信号:将信号的处理设置为SIG_IGN,SIGKILL和SIGSTOP不能被忽略
  • 默认处理:将信号处理设置为SIG_DFL,大多数情况的默认处理是终止进程,极个别的信号采用忽略方式,如SIGCHLD,SIGURG(带外数据到达时发送)

 

 

信号 动作 解释
SIGHUP 1   终端线路挂断
SIGINT 2 Term 键盘输入的中断命令,从终端输入 Ctrl-C 时发生
SIGQUIT 3 Core 键盘输入的退出命令
SIGILL 4 Core 错误指令
SIGABRT 6 Core abort(3)发出的中止信号
SIGFPE 8 Core 浮点数异常
SIGKILL 9 Term KILL信号
SIGSEGV 11 Core 非法内存访问
SIGPIPE 13 Term 管道断开
SIGALRM 14 Term alarm(2)发出的中止信号
SIGTERM 15 Term 强制中止信号
SIGUSR1 30,10,16 Term 用户自定义信号1
SIGUSR2 31,12,17 Term 用户自定义信号2
SIGCHLD 20,17,18 Ign 子进程中止信号
SIGCONT 19,18,25 Cont 继续执行一个停止的进程
SIGSTOP 17,19,23 Stop 非终端来的停止信号
SIGTSTP 18,20,24 Stop 终端来的停止信号
SIGTTIN 21,21,26 Stop 后台进程读终端
SIGTTOU 22,22,27 Stop 后台进程写终端

抱歉!评论已关闭.