首页 > 代码库 > 基于 linux的 信号详解

基于 linux的 信号详解

1、信号:

      每个信号都一个一个名字,都已SIG开头;不存在编号为0的信号;


2、产生信号的条件:

      a、用户使用了终端按键;

      b、硬件异常(如除0,无效的内存引用);

      c、进程调用kill(2)函数,将信号发送给另一个进程;(注意,另一进程必须和发送进程的的所有者必须相同,或者发送信号的所有者必须是超级用户);

      d、当检查到某种软件条件已经发生时,将其通知相关进程时,也产生信号;


3、信号是异步事件的经典;信号的产生是随机的,进程不能通过测试一个变量来测试是否出现了信号,而是必须告诉内核,在该信号出现时,请执行下列操作;


4、内核对出现的信号可有三种动作可选:

      a、忽略此信号(注意:SIGKILL 信号 和 SIGSTOP信号,不可被忽略);

      b、捕捉信号;简单来说,就是抓到该信号后,执行进程提供给内核的处理函数;注意,SIGKILL和SIGSTOP不可被捕获; 

      c、执行默认动作;每种信号都有默认动作,大多数信号的默认动作是终止进程;


5、常见信号解释:

      a、SIGCHLD     在一个进程终止时,将SIGCHLD信号发送给其父进程;

      b、SIGFPE        算数异常;

      c、SIGPIPE       写管道,但是管道的读端已经终止,会产生此信号;

      d、SIGPWR      不间断电源(UPS)失效;

      e、SIGSEGV     无效的内存引用;

      f、 SIGSTOP     终止进程;

      g、SIGSYS       无效的系统调用;

      h、SIGTERM     由kill(1)命令发送的终止信号;

      i、 SIGXFSZ      进程超过了其软文件长度的限制;


6、信号处理函数:

       Sigfunc *signal(int,  Sigfunc*);

       参数1:信号宏;

       参数2:处理函数;

                     特殊情况:有几个默认的函数宏,用户默认,忽略,错误处理;

                      #define SIG_ERR   (void (*)()) -1;

                      #define SIG_DFL   (void (*)()) 0;

                      #define SIG_IGN   (void (*)()) 1;

       返回值:函数指针;


7、kill(1)  命令和kill(2)函数只是将一个信号送给一个进程或者进程组,信号是否终止,取决于信号的类型,以及进程是否安排了捕捉该信号;


8、当一个进程用fork时,其子进程继承父进程的信号处理方式;


9、  pause函数;

        #include <unistd.h>

        int pause(void);

        该函数,是本进程挂起,指导捕捉到一个信号;只有执行了信号处理函数,并从其中返回时,pause才会返回;在这种情况下,返回是-1;并将error设置为EINTR;

        pause函数,使自己休眠,直到捕捉到一个信号;


10、当捕捉到某个信号是,被中断的是内核中执行的系统调用;


12、不可重入函数的原因:

         a、该函数使用了静态数据结构;

         b、调用了malloc或者free;

         c、使用了表中I/O函数,因为表中I/O函数,很多实现都使用了全局的数据结构;


13、在信号产生和信号递达的间隔内,信号处于未决状态;


14、每个信号都有一个信号屏蔽字,该信号屏蔽字规定了要阻塞送到该进程的的信号集。当某个信号递送时即将到达时,发现对应位被设置,则他当前是被阻塞的;


15、kill函数:

        #include<signal.h>

       int kill(pid_t pid, int signo);

       作用:将信号发送给某个进程或者进程组;

        参数1: pid > 0,表示将该信号发送给ID 为pid的进程;

                       pid == 0 ; 将进程发送给本组所有进程;

                       pid < 0 ,将信号发送给进程组ID 等于 pid绝对值的组;

                       pid == -1; 表示该进程把信号发送给 “所有自己有权发送给”的那些进程;


16、将编号为0 的信号定义为空信号,使用kill时,signo为0 ,可以进行错误检查,但是不发任何信号,这常被用来测试一个进程是否存在,如果不存在,则返回-1;并将error置为ESRCH;



17、raise函数;

        int raise(int signo)函数,用于向进程自身发送信号;


18、alarm函数:

        #include <unistd.h>

        unsigned int alarm(unsigned int seconds);

        使用该函数,设定一个定时器,定时器过期时,会产生SIGALRM信号,该信号的默认动作是终止进程;

        每个进程同时只能有一个alarm,否则,新使用的alarm会替代旧的alarm,新alarm 会将旧alarm所剩余的时间返回;

        将seconds可以取消以前的闹钟,返回余留值;

        注意:如果要使用alarm函数,且在在捕捉到SIGALRM信号后,要做相应的处理,则应该在调用alarm函数之前,设置该信号的处理函数;


19、信号集:

      信号集:告诉内核不允许发生该信号集中的信号;

      五个基本的信号集操作函数:

      #include <signal.h>

      int sigemptyset(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);

      判断signo是否是信号集成员;


20、sigprocmask函数

        

        #include<signal.h>

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

        成功则返回0,出错返回-1;

       

        当oset 为非空指针时,进程的当前信号屏蔽字通过oset返回;

        当set不是空指针时,how用来说明修改当前信号屏蔽字的方式,修改方式包括:SIG_BLOCK(set 和 oset的并集);SIG_UNBLOCK(oset与 “set 信号集的补集“的交集)

SIG_SETMASK(指定用set替代旧的信号集);


21、 sigpending 函数:

         用于返回被阻塞而不能递送的信号集;


22、sigaction函数;

        功能是检查或者修改与指定信号的相关联的处理动作;与signal作用类似;     


        #include <signal.h>

        int sigaction(int signo, const struct sigaction *restrict act, struct sigaction *restrict oact);

        返回值:成功则返回0, 出错返回-1;

        signo : 表示要检查或者修改具体动作相关联的某个信号;

        struct sigaction 结构体:

        struct sigaction{

        void  (*sa_handler)(int) ;            //与信号相关的处理函数或者SIG_IGN,SIG_DEF;

        sigset_t sa_mask;                      //信号集;在调用该函数之前,首先应该用此设置信号集;

        int sa_flags;                               //包含对信号处理的各个选项;

        void  (*sa_sigaction)(int, siginfo_t *, void *);   当在flag中使用了SA_SIGINFO标志时,使用此处理程序;(注意,此函数指针和第一个处理信号的函数指针,两者只能使用其中之一;)zaisiginfo_t结构体中包含了信号产生原因的相关信息;

                     


本文出自 “10891086” 博客,请务必保留此出处http://10901086.blog.51cto.com/10891086/1917537

基于 linux的 信号详解