日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux系统编程----7(信号集,信号屏蔽,信号捕捉)

發布時間:2023/11/30 linux 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux系统编程----7(信号集,信号屏蔽,信号捕捉) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

信號集操作函數

內核通過讀取未決信號集來判斷信號是否應被處理。信號屏蔽字 mask 可以影響未決信號集。而我們可以在應 用程序中自定義 set 來改變 mask。已達到屏蔽指定信號的目的。

信號集設定

  • sigset_t set; //typedef unsigned long sigset_t;
  • int sigemptyset(sigset_t* set); 將某個信號集清 0 成功:0;失敗:-1
  • int sigfillset(sigset_t* set); 將某個信號集置 1 成功:0;失敗:-1
  • int sigaddset(sigset_t* set,int signum); 將某個信號加入信號集 成功:0;失敗:-1
  • int sigdelset(sigset_t* set,int signum); 將某個信號清出信號集 成功:0;失敗:-1
  • int sigismember(const sigset_t* set,int signum);判斷某個信號是否在信號集中 返回值:在集合:1;不在:0; 出錯:-1
    sigset_t 類型的本質是位圖。但不應該直接使用位操作,而應該使用上述函數,保證跨系統操作有效。
  • sigprocmask 函數

    用來屏蔽信號、解除屏蔽也使用該函數。其本質,讀取或修改進程的信號屏蔽字(PCB 中)

    嚴格注意

    屏蔽信號:只是將信號處理延后執行(延至解除屏蔽);而忽略表示將信號丟處理。

    函數格式

    int sigprocmask(int how,const sigset_t* set,sigset_t* oldset); 成功:0;失敗:-1,設置 errno

    參數

    set:傳入參數,是一個位圖,set 中哪位置 1,就表示當前進程屏蔽哪個信號。
    oldset:傳出參數,保存舊的信號屏蔽集。
    how 參數取值: 假設當前的信號屏蔽字為 mask

  • SIG_BLOCK: 當 how 設置為此值,set 表示需要屏蔽的信號。相當于 mask=mask|set
  • SIG_UNBLOCK: 當 how 設置為此,set 表示需要解除屏蔽的信號。相當于 mask=mask&~set
  • SIG_SETMASK: 當 how 設置為此,set 表示用于替代原始屏蔽及的新屏蔽集。相當于 mask=set 若,調用 sigprocmask 解除了對當前若干個信號的阻塞,則在 sigprocmask 返回前,至少將其中一 個信號遞達。
  • sigpending 函數

    讀取當前進程的未決信號集
    int sigpending(sigset_t* set); set 傳出參數。 返回值:成功:0;失敗:-1,設置 errno

    編寫程序。把所有常規信號的未決狀態打印至屏幕。
    /** 打印未決信號集*/#include<stdio.h> #include<signal.h> #include<unistd.h>void printped(sigset_t * ped) {int i;//常用的是前32個信號for(i = 1; i < 32; i++ ){if(sigismember(ped,i) == 1){ //在集合中putchar('1');}else{putchar('0');} } printf("\n"); }int main(void ){sigset_t myset, oldset ,ped;sigemptyset(&myset);sigaddset(&myset,SIGQUIT);//屏蔽系統本身3號信號sigaddset(&myset,SIGINT);//屏蔽系統本身的2號信號sigaddset(&myset,SIGTSTP);sigaddset(&myset,SIGSEGV);sigaddset(&myset,SIGKILL); sigprocmask(SIG_BLOCK,&myset,&oldset);while(1){sigpending(&ped);//判斷集合中每個信號的對應位是0還是1printped(&ped);sleep(1);}return 0; }

    9號信號和19號信號不允許設置屏蔽

    信號捕捉

    signal 函數

    注冊一個信號捕捉函數:

    typedef void(*sighandler_t)(int); sighandler_t signal(int signum,sighandler_t handler);

    該函數由 ANSI 定義,由于歷史原因在不同版本的 Unix 和不同版本的 Linux 中可能有不同的行為。因此應該盡 量避免使用它,取而代之使用 sigaction 函數。

    void (*signal (int signum,void ( *sighandler_t)(int)))(int); #include<stdio.h> #include<sys/time.h> #include<signal.h>void myfunc(int signo) {printf("hello world\n"); }int main(void) {struct itimerval it,oldit;signal(SIGALRM,myfunc); //注冊SIGALRM信號的捕捉處理函數//sighandler_t tml=signal(SIGALRM,myfunc);it.it_value.tv_sec=5;//定時5秒中it.it_value.tv_usec=0;//0微秒it.it_interval.tv_sec=3;//第一個和第二個之間間隔時間3秒it.it_interval.tv_usec=0;if(setitimer(ITIMER_REAL,&it,&oldit) == -1){perror("setitimer error");return -1; } while(1);return 0; }


    第一個出來是5秒,隨后都是3秒出來一個

    #include<stdio.h> #include<signal.h> #include<errno.h> #include<stdlib.h> #include<unistd.h> typedef void(*sighandler_t)(int);void catchsigint(int singo) {printf("-----catch\n"); }int main(void) {sighandler_t handler;handler=signal(SIGINT,catchsigint);//捕捉if(handler == SIG_ERR){perror("signal error");exit(1);} while(1);return 0; }

    sigaction 函數

    修改信號處理動作(通常在 Linux 用其來注冊一個信號的捕捉函數)

    int sigaction (int signum,const struct sigaction*act,struct sigaction*oldact) 成功:0;失敗:-1,設置 errno

    參數:

  • act:傳入參數,新的處理方式。
  • oldact:傳出參數,舊的處理方式。
  • struct sigaction 結構體

  • struct sigaction {
  • void (*sa_handler)(int); //函數名
  • void (sa_sigaction)(int,siginfo_t,void*);
  • sigset_t sa_mask; //用于指定在信號捕捉期間屏蔽的信號
  • int sa_flags; //標志位
  • void (*sa_restorer)(void);
    };
    sa_restorer:該元素是過時的,不應該使用,POSIX.1 標準將不指定該元素。(棄用) sa_sigaction:當 sa_flags 被指定為 SA_SIGINFO 標志時,使用該信號處理程序。(很少使用)
  • 重點掌握:

  • sa_handler:指定信號捕捉后的處理函數名(即注冊函數)。也可賦值為 SIG_IGN 表忽略 或 SIG_DFL 表執行默 認動作

  • sa_mask: 調用信號處理函數時,所要屏蔽的信號集合(信號屏蔽字)。注意:僅在處理函數被調用期間屏蔽 生效,是臨時性設置。

  • sa_flags:通常設置為 0,表使用默認屬性。

    #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<signal.h>void docatch(int signo) {printf("%d signal is catched\n",signo); }int main(void) {int ret;struct sigaction act;act.sa_handler = docatch;sigemptyset(&act.sa_mask); sigaddset(&act.sa_mask,SIGQUIT);act.sa_flags = 0; //默認屬性 信號捕捉函數執行期間自動屏蔽本信號 ret = sigaction(SIGINT,&act,NULL);if(ret < 0){ perror("sigaction error");exit(1);} while(1);return 0; }
  • 信號捕捉特性

  • 進程正常運行時,默認 PCB 中有一個信號屏蔽字,假定為☆,它決定了進程自動屏蔽哪些信號。當注冊了 某個信號捕捉函數,捕捉到該信號以后,要調用該函數。而該函數有可能執行很長時間,在這期間所屏蔽 的信號不由☆來指定。而是用 sa_mask 來指定。調用完信號處理函數,再恢復為☆。
  • XXX 信號捕捉函數執行期間,XXX 信號自動被屏蔽。
  • 阻塞的常規信號不支持排隊,產生多次只記錄一次。(后 32 個實時信號支持排隊)
  • 總結

    以上是生活随笔為你收集整理的Linux系统编程----7(信号集,信号屏蔽,信号捕捉)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。