歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux下的信號處理函數總結

1.信號處理函數

相關函數原型如下:

#include <signal.h>
sighandler_t signal(int signum, sighandler_t handler);

第一參數是信號
第二個參數是信號處理器:
            1.可以是SIG_DFL,信號的默認動作
            2. 可以是SIG_IGN,忽略該信號
            3. 一個帶有一個整型參數的處理函數。

#include <signal.h>
int sigaction(int signum, const struct sigaction *act,
                    struct sigaction *oldact);
signum  要處理的信號 
act    指針,指向描述操作的結構 如何響應信號的結構體
oldact  指針,指向描述被替換操作的結構 被替換的處理設置的結構體
          struct sigaction {
              void    (*sa_handler)(int);
              void    (*sa_sigaction)(int, siginfo_t *, void *);
              sigset_t  sa_mask;
              int        sa_flags;
              void    (*sa_restorer)(void);
          };

進程該如何處理信號(早期的信號處理機制):

進程可以通過signal系統調用來告訴內核該怎麼去處理信號

    1.接受默認處理

        按照信號本來的意圖區處理 signal(SIGINT,SIG_DFL)

    2.忽略信號

        signal(SIGINT,SIG_IGN) 忽略SIGINT信號

    3.調用一個函數

        signal(SIGINT,functionname)

2.早期的信號處理機制存在的問題

    一:信號處理函數每次調用後都要被禁用(根據系統的不同而不不同)

    二:不知道信號被發送的原因

    三:處理函數中不能安全地阻塞其他信號

    四:不支持信號中斷,信號會被阻塞。(不同的系統可能不同)

3.POSIX信號處理函數

POSIX提供了sigaction這個信號處理函數。相應的提供了一個sigaction結構體。

這個結構體中的sa_flags定義了一些如何處理早期信號機制存在的問題的標志位,可以通過與操作進行組合。

下面僅列出部分標志位: 
SA_RESETHAND 當處理函數被調用時重置而不是禁用
SA_NODEFER    關閉信號阻塞,允許遞歸調用信號
SA_RESTAAT    當系統調用針對一些慢速設備或類似的系統調用重新開始而不是返回
SA_SIGINFO    指明使用sa_sigaction函數的值,,如果這個位沒有設置,那麼就使用sa_handle指向的函數的值,如果sa_sigaction被使用了,那麼傳遞給函數的將不只是信號的編號,而是信號產生的原因和條件的結構體。

下面的一個例子將演示如何使用sigaction來實現安全的阻塞其它信號

#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#define INPUTLEN 100

int main ( int argc, char *argv[] )
{
        struct sigaction newhandler;
        #定義一個信號集
        sigset_t        blocked;
        char    x[INPUTLEN];
        #設置信號處理函數
        newhandler.sa_handler = inthandler;
        #設置信號處理函數重置
        newhandler.sa_flags = SA_RESETHAND|SA_RESTART
        #清空信號集
        sigemptyset(&blocked);
        #添加SIGQUIT信號集
        sigaddset(&block,SIGQUIT);
        #設置屏蔽的信號集
        newhandler.sa_mask = blocked;
        #裝載信號
        if(sigaction(SIGINT,&newhandler,NULL) == -1)
                perror("sigaction");
        else
                while(1){
                        fgets(x,INPUTLEN,stdin);
                        printf("INput: %s",x);
                }
        return EXIT_SUCCESS;
}
                /* ----------  end of function main  ---------- */

void inthandler (int s)
{
        printf("Called with signal %d\n",s);
        sleep(s);
        printf("done handling signal %d\n",s);
}              /* -----  end of function inthandler  ----- */

Linux編程---信號處理 http://www.linuxidc.com/Linux/2014-06/103489.htm

Linux的信號處理和實際使用(結合Redis分析) http://www.linuxidc.com/Linux/2014-03/98787.htm

Linux-信號處理 http://www.linuxidc.com/Linux/2012-06/63883.htm

一步一步學Linux C:信號處理潛在危險!!! http://www.linuxidc.com/Linux/2012-03/57195.htm

一步一步學Linux C:信號處理方法 && 實際應用 http://www.linuxidc.com/Linux/2012-03/57074.htm

一步一步學Linux C:信號處理 http://www.linuxidc.com/Linux/2012-03/56809.htm

Copyright © Linux教程網 All Rights Reserved