linux signal函数用法,linux信号机制之sigaction构造体浅析,signal 函数,信号捕捉.

来自:http://hi.baidu.com/phenix_yw/blog/item/6eb4ca391d1479f23a87ce19.html

信号安装函数sigaction(int signum,const struct sigaction

*act,structsigaction*oldact)的第二个参数是一个指向sigaction构造的指针(构造体名目与函数名一样,千万别弄混同了)。在构造sigaction的实例中,指定了对特定信号的处理,信号所递交的消息,信号处理函数施征途序中应屏障掉哪些函数等。当然,此指针也可感受NULL,历程会以默认措施处理信号。以下就容易推荐一下sigaction构造以及等闲的用法。

对于内核头文件而言,struct sigaction

构造体定义在kernel/include/asm/signal.h,此头文件又被kernel/include/linux/signal.h包括。

对于用户空间的头文件而言,struct

sigaction定义在/usr/include/bits/sigaction.h,此头文件又被/usr/include/signal.h包括,因而利用过程中万一用到此构造,凡是#include即可。当心内核中的定义和利用过程中的定义是不一样的,内核空间的sigaction构造只扶持函数种类为__sighandler_t的信号处理函数,不能处理信号递交的额外消息。翔实定义如下:

……

typedef void (*__sighandler_t)(int);

……

#ifdef __KERNEL__

struct old_sigaction {

__sighandler_t sa_handler;

old_sigset_t sa_mask;

unsigned long sa_flags;

void (*sa_restorer)(void);

};

struct sigaction {

__sighandler_t sa_handler;

unsigned long sa_flags;

void (*sa_restorer)(void);

sigset_t sa_mask;

};

struct k_sigaction {

struct sigaction sa;

};

#else

struct sigaction {

union {

__sighandler_t _sa_handler;

void (*_sa_sigaction)(int, struct siginfo *, void *);

} _u;

sigset_t sa_mask;

unsigned long sa_flags;

void (*sa_restorer)(void);

};

#define sa_handler _u._sa_handler

#define sa_sigaction _u._sa_sigaction

#endif

sa_handler的原型是一个参数为int,归来种类为void的函数指针。参数即为信号值,因而信号不能递交除信号值之外的任何消息;

sa_sigaction的原型是一个带三个参数,种类离别为int,struct siginfo

*,void*,归来种类为void的函数指针。第一个参数为信号值;第二个参数是一个指向structsiginfo构造的指针,此构造中包括信号携带的数据值;第三个参数没利于用。

sa_mask指定在信号处理过程施征途序中,哪些信号该当被阻塞。默认目前信号本身被阻塞。

sa_flags包括了众多符号位,比拟重要的一个是SA_SIGINFO,当设定了该符号位时,表示信号附带的参数能够递交到信号处理函数中。即便sa_sigaction指定信号处理函数,万一不设置SA_SIGINFO,信号处理函数同样不能获得信号递交到来的数据,在信号处理函数中对这些消息的拜会都将导致段讹谬。

sa_restorer已过时,POSIX不扶持它,不应再利用。

因而,当你的信号必需接收附带消息的时候,你定然给sa_sigaction赋信号处理函数指针,同时还要给sa_flags赋SA_SIGINFO,相仿下面的代码:

#include

……

void sig_handler_with_arg(int sig,siginfo_t *sig_info,void

*unused){……}

int main(int argc,char **argv)

{

struct sigaction sig_act;

……

sigemptyset(&sig_act.sa_mask);

sig_act.sa_sigaction=sig_handler_with_arg;

sig_act.sa_flags=SA_SIGINFO;

……

}

万一你的利用过程只必需接收信号,而无须要接收额外消息,那你必需的设置的是sa_handler,而不是sa_sigaction,你的过程可能相仿下面的代码:

#include

……

void sig_handler(int

sig){……}

int main(int argc,char **argv)

{

struct sigaction sig_act;

……

sigemptyset(&sig_act.sa_mask);

sig_act.sa_handler=sig_handler;

sig_act.sa_flags=0;

……

}

万一必需更翔实解释,请参看sigaction的man手册。

赔偿:

简而言之即便:

//自定义退出函数

sigact.sa_handler = mysighandler;

sigemptyset(&sigact.sa_mask);

sigact.sa_flags = 0;

sigaction(SIGINT, &sigact, NULL);

sigaction(SIGTERM, &sigact, NULL);

sigaction(SIGQUIT, &sigact, NULL);

可能利用signal函数举行信号捕捉:

void (*signal(int signo, void (*handler)(int)))(int);

当signal到来时,过程运行某函数,函数由你自己指定。

附带各种信号定义:

在终端利用kill -l 号召能够揭示所有的信号。

$kill -l

1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL

5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE

9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2

13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT

17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP

21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU

25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH

29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN

35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4

39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8

43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46)

SIGRTMIN+12

47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50)

SIGRTMAX-14

51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54)

SIGRTMAX-10

55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6

59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2

63) SIGRTMAX-1 64) SIGRTMAX

其中前面31个信号为不可靠信号(非实时的,可能会揭示信号的失落),后面的信号为可靠信号(实时的real_time,对信号

排队,不会失落)。

1) SIGHUP (挂起) 当运行历程的用户吊销时通知该历程,使历程终止

2) SIGINT (间断) 当用户按下时,通知前台历程组终止历程

3) SIGQUIT (退出) 用户按下或时通知历程,使历程终止

4) SIGILL (违法号召) 厉行了违法号召,如可厉行文件本身揭示讹谬、试图厉行数据段、堆栈溢出

5) SIGTRAP 由断点号召或其它trap号召发生. 由debugger利用

6) SIGABRT (失常间断) 调用abort函数生成的信号

7) SIGBUS 违法地址, 包括内存地址对齐(alignment)出错. eg: 拜会一个四个字长的整数,

但其地址不是4的倍数.

8) SIGFPE (算术失常) 发生致命算术计算讹谬,包括浮点计算讹谬、溢出及除数为0.

9) SIGKILL (确认杀害) 当用户穿越kill -9号召向历程发送信号时,可靠的终止历程

10) SIGUSR1 用户利用

11) SIGSEGV (段越界) 当历程试探拜会不属于自己的内存空间导致内存讹谬时,终止历程

12) SIGUSR2 用户利用

13) SIGPIPE 写至无读历程zi.zirenshengwu.com的管道,

可能Socket通信SOCT_STREAM的读历程曾经终止,而再写入。

14) SIGALRM (超时) alarm函数利用该信号,时钟定时器超时响应

15) SIGTERM (软间断) 利用不带参数的kill号召时终止历程

17) SIGCHLD (子历程告终) 当子历程终止时通知父历程

18) SIGCONT (暂停历程继续) 让一个静止(stopped)的历程继续厉行. 本信号不能被阻塞.

19) SIGSTOP (静止) 作业扼制信号,暂停静止(stopped)历程的厉行. 本信号不能被阻塞, 处理或疏忽.

20) SIGTSTP (暂停/静止) 交互式静止信号, Ctrl-Z 公布这个信号

21) SIGTTIN 当后台作业要从用户终端读数据时, 终端驱动过程发生SIGTTIN信号

22) SIGTTOU 当后台作业要往用户终端写数据时, 终端驱动过程发生SIGTTOU信号

23) SIGURG

有"紧迫"数据或网络上带外数据到达socket时发生.

24) SIGXCPU 超过CPU工夫资源局限. 这个局限能够由getrlimit/setrlimit来读取/改换。

25) SIGXFSZ 当历程空想放大文件以至于超过文件大小资源局限。

26) SIGVTALRM 虚构时钟信号. 相仿于SIGALRM, 然而计算的是该历程挪借的CPU工夫.

27) SIGPROF (梗概工夫超时) setitimer(2)函数设置的梗概普查间隔计时器(profiling

interval timer)

28) SIGWINCH 窗口大小改换时公布.

29) SIGIO(异步I/O) 文件描写符准备就绪, 能够开始举行输入/输出垄断.

30) SIGPWR 电源失效/重启用

31) SIGSYS 违法的系统调用。

在以上列出的信号中,

过程不可捉拿、阻塞或疏忽的信号有:SIGKILL,SIGSTOP

不能还原至默认动作的信号有:SIGILL,SIGTRAP

默认会导致历程流产的信号有:SIGABRT,SIGBUS,SIGFPE,SIGILL,SIGIOT,SIGQUIT,SIGSEGV,SIGTRAP,SIGXCPU,SIGXFSZ

默认会导致历程退出的信号有:SIGALRM,SIGHUP,SIGINT,SIGKILL,SIGPIPE,SIGPOLL,SIGPROF,SIGSYS,SIGTERM,SIGUSR1,SIGUSR2,SIGVTALRM

默认会导致历程静止的信号有:SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU

默认历程疏忽的信号有:SIGCHLD,SIGPWR,SIGURG,SIGWINCH

另外,SIGIO在SVR4是退出,在4.3BSD中是疏忽;SIGCONT在历程挂起时是继续,否则是疏忽,不能被阻塞。

在Unix/Linux中signal函数是比拟混杂的一个,其定义原型如下:void (*signal(int signo,void

(*func)(int))) (int)这个函数中,最外层的函数体void (* XXX

)(int)阐明是一个指针,指向一个函数XXX的指针,XXX所代表的函数必需一个int型的参数,归来voidsignal(int

signo,

void(*func)(int))是signal函数的主体.必需两个参数int型的signo以及一个指向函数的函数.void

(*func)(int).正是由于其混杂性,在[Plauger 1992]用typedef来对其举行简化typedef void

Sigfuc(int);//这里能够当做一个归来值 .再对signal函数举行简化即便这么的了Sigfunc

*signal(int,Sigfuc *);在signal.h头文件中还有以下几个定义#define SIG_ERR (void

(*)())-1#define SIG_DFL (void (*)())0#define SIG_IGN (void

(*)())1并且,代码审查对肃清一些尤其细节的讹谬大有裨益,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值