标准库函数---信号处理函数--signal

来源:互联网 发布:网络广告创意方法 编辑:程序博客网 时间:2024/05/16 01:54

一  信号处理

<signal.h>

头文件<signal.h>中提供了一些用于处理程序运行期间所引发的异常条件的功能,如处理来源于外部的中断信号或程序执行期间出现的错误等事件。

9.1 signal

#include <signal.h>void (*signal(int sig, void (*handler)(int)))(int);

signal()用于确定以后当信号sig出现时的处理方法。如果handler的值是SIG_DFL,那么就采用实现定义的缺省行为;如果handler的值是SIG_IGN,那么就忽略该信号;否则,调用handler所指向的函数(参数为信号类型)。有效的信号包括:

SIGABRT异常终止,如调用abort()。SIGFPE算术运算出错,如除数为0或溢出。SIGILL非法函数映象,如非法指令。SIGINT交互式信号,如中断。SIGSEGV非法访问存储器,如访问不存在的内存单元。SIGTERM发送给本程序的终止请求信号。

signal()返回信号sig原来的的handler;如果出错,则返回SIG_ERR。

当随后出现信号sig时,就中断正在执行的操作,转而执行信号处理函数(*handler)(sig)。如果从信号处理程序中返回,则从中断的位置继续执行。

信号的初始状态由实现定义。

9.2 raise

#include <signal.h>int raise(int sig);

向程序发送信号sig。如果发送不成功,就返回一个非0值。

转载自》http://www.swordair.com/docs/c-language-standard-library/chapter-9/

2 信号集

sigset_t

  
信号集及信号集操作函数:信号集被定义为一种数据类型:
typedef struct {
unsigned long sig[_NSIG_WORDS];
} sigset_t
信号集用来描述信号的集合,linux所支持的所有信号可以全部或部分的出现在信号集中,主要与信号阻塞相关函数配合使用。下面是为信号集操作定义的相关函数:
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum)
int sigdelset(sigset_t *set, int signum);
int sigismember(const sigset_t *set, int signum);int sigaction( int sig, const struct sigaction *act,struct sigaction *oact );
头文件
#include <signal.h>
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指向的信号集中。
int sigaction( int sig, const struct sigaction *act,struct sigaction *oact )检查、修改和指定信号相关联的信号响应。

百度百科

3 sigaction


sigaction函数的功能是检查或修改与指定信号相关联的处理动作(可同时两种操作)。

他是POSIX的信号接口,而signal()是标准C的信号接口(如果程序必须在非POSIX系统上运行,那么就应该使用这个接口)

给信号signum设置新的信号处理函数act, 同时保留该信号原有的信号处理函数oldact

intsigaction(int signo,conststruct sigaction*restrict act,

             struct sigaction*restrict oact);

结构sigaction定义如下:

structsigaction{
  void (*sa_handler)(int);
   sigset_t sa_mask;
  int sa_flag;
  void (*sa_sigaction)(int,siginfo_t*,void*);
};

sa_handler字段包含一个信号捕捉函数的地址

sa_mask字段说明了一个信号集,在调用该信号捕捉函数之前,这一信号集要加进进程的信号屏蔽字中。仅当从信号捕捉函数返回时再将进程的信号屏蔽字复位为原先值。

sa_flag是一个选项,主要理解两个

SA_INTERRUPT 由此信号中断的系统调用不会自动重启
SA_RESTART 由此信号中断的系统调用会自动重启

SA_SIGINFO 提供附加信息,一个指向siginfo结构的指针以及一个指向进程上下文标识符的指针

最后一个参数是一个替代的信号处理程序,当设置SA_SIGINFO时才会用他。



参考:http://blog.chinaunix.net/uid-1877180-id-3011232.html


4 信号屏蔽字
一个进程的信号屏蔽字规定了当前阻塞而不能递送给该进程的信号集。

(1)


头文件
#include<signal.h>

函数原型

int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oldset);

根据how的方式对set和oldset进行组合,确定最后最终的信号集合。这个信号集合就是信号屏蔽字。

函数说明

一个进程的信号屏蔽字规定了当前阻塞而不能递送给该进程的信号集。sigprocmask()可以用来检测或改变目前的信号屏蔽字,其操作依参数how来决定,如果参数oldset不是NULL指针,那么目前的信号屏蔽字会由此指针返回。如果set是一个非空指针,则参数how指示如何修改当前信号屏蔽字。每个进程都有一个用来描述哪些信号递送到进程时将被阻塞的信号集,该信号集中的所有信号在递送到进程后都将被阻塞。
参数how:
SIG_BLOCK
该进程新的信号屏蔽字是其当前信号屏蔽字和set指向信号集的并集。set包含了我
们希望阻塞的附加信号。
SIG_UNBLOCK
该进程新的信号屏蔽字是其当前信号屏蔽字和set所指向信号集的补集的交集。set包含了
我们希望解除阻塞的信号.
SIG_SETMASK
该进程新的信号屏蔽是set指向的值
如果set是个空指针,则不改变该进程的信号屏蔽字,how的值也无意义。


(2) pthread_sigmask


  • pthread_sigmask 用来定义线程的信号掩码
  • 其接口与 sigprocmask 一样-----------------这是相对sigprocmask的区别。
  • 用在多线程环境中

概念

  • 按照 POSIX, 异步 (外部) 信号发送到整个进程.
  • 所有线程共享同一个设置, 即通过 sigaction 设置的线程处置方法.
  • 每个线程有自己的信号掩码, 线程库根据该掩码决定将信号发送到哪个线程.
  • 由于 Linux 线程实现上的独特性, 外部信号始终发送到特定的线程.
http://www.cnblogs.com/qq78292959/archive/2012/04/05/2432985.html



原创粉丝点击