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

歡迎訪問 生活随笔!

生活随笔

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

linux

linux 信号signal和sigaction理解

發布時間:2023/11/30 linux 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux 信号signal和sigaction理解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載:http://blog.csdn.net/beginning1126/article/details/8680757

今天看到unp時發現之前對signal到理解實在淺顯,今天拿來單獨學習討論下。


signal,此函數相對簡單一些,給定一個信號,給出信號處理函數則可,當然,函數簡單,其功能也相對簡單許多,簡單給出個函數例子如下:

[cpp]?view plaincopy
  • ?1?#include?<signal.h>??
  • ?2?#include?<stdio.h>??
  • ?3?#include?<unistd.h>??
  • ?4???
  • ?5?void?ouch(int?sig)??
  • ?6?{??
  • ?7?????printf("I?got?signal?%d\n",?sig);??
  • ?8?????//?(void)?signal(SIGINT,?SIG_DFL);??
  • ?9?????//(void)?signal(SIGINT,?ouch);??
  • 10???
  • 11?}??
  • 12???
  • 13???
  • 14???
  • 15?int?main()??
  • 16?{??
  • 17?????(void)?signal(SIGINT,?ouch);??
  • 18???
  • 19?????while(1)??
  • 20?????{??
  • 21?????????printf("hello?world...\n");??
  • 22?????????sleep(1);??
  • 23?????}??
  • 24?}??
  • 當然,實際運用中,需要對不同到signal設定不同的到信號處理函數,SIG_IGN忽略/SIG_DFL默認,這倆宏也可以作為信號處理函數。同時SIGSTOP/SIGKILL這倆信號無法捕獲和忽略。注意,經過實驗發現,signal函數也會堵塞當前正在處理的signal,但是沒有辦法阻塞其它signal,比如正在處理SIG_INT,再來一個SIG_INT則會堵塞,但是來SIG_QUIT則會被其中斷,如果SIG_QUIT有處理,則需要等待SIG_QUIT處理完了,SIG_INT才會接著剛才處理。


    sigaction,這個相對麻煩一些,函數原型如下:

    int sigaction(int sig, const struct sigaction *act, struct sigaction *oact);

    函數到關鍵就在于struct sigaction

    [cpp]?view plaincopy
  • stuct?sigaction??
  • {??
  • ??????void?(*)(int)?sa_handle;??
  • ??????sigset_t?sa_mask;??
  • ??????int?sa_flags;??
  • }??

  • [cpp]?view plaincopy
  • 1?#include?<signal.h>??
  • ??2?#include?<stdio.h>??
  • ??3?#include?<unistd.h>??
  • ??4???
  • ??5???
  • ??6?void?ouch(int?sig)??
  • ??7?{??
  • ??8?????printf("oh,?got?a?signal?%d\n",?sig);??
  • ??9???
  • ?10?????int?i?=?0;??
  • ?11?????for?(i?=?0;?i?<?5;?i++)??
  • ?12?????{??
  • ?13?????????printf("signal?func?%d\n",?i);??
  • ?14?????????sleep(1);??
  • ?15?????}??
  • ?16?}??
  • ?17???
  • ?18???
  • ?19?int?main()??
  • ?20?{??
  • ?21?????struct?sigaction?act;??
  • ?22?????act.sa_handler?=?ouch;??
  • ?23?????sigemptyset(&act.sa_mask);??
  • ?24?????sigaddset(&act.sa_mask,?SIGQUIT);??
  • ?25?????//?act.sa_flags?=?SA_RESETHAND;??
  • ?26?????//?act.sa_flags?=?SA_NODEFER;??
  • ?27?????act.sa_flags?=?0;??
  • ?28???
  • ?29?????sigaction(SIGINT,?&act,?0);??
  • ?30???
  • ?31???
  • ?32?????struct?sigaction?act_2;??
  • ?33?????act_2.sa_handler?=?ouch;??
  • ?34?????sigemptyset(&act_2.sa_mask);??
  • ?35?????act.sa_flags?=?0;??
  • ?36?????sigaction(SIGQUIT,?&act_2,?0);??
  • ?37???
  • ????????while(1)??
  • ????????{??
  • ?????????????sleep(1);??
  • ????????}??
  • ?38?????return;??
  • ??
  • ????}??

  • 1. 阻塞,sigaction函數有阻塞的功能,比如SIGINT信號來了,進入信號處理函數,默認情況下,在信號處理函數未完成之前,如果又來了一個SIGINT信號,其將被阻塞,只有信號處理函數處理完畢,才會對后來的SIGINT再進行處理,同時后續無論來多少個SIGINT,僅處理一個SIGINT,sigaction會對后續SIGINT進行排隊合并處理。

    2. sa_mask,信號屏蔽集,可以通過函數sigemptyset/sigaddset等來清空和增加需要屏蔽的信號,上面代碼中,對信號SIGINT處理時,如果來信號SIGQUIT,其將被屏蔽,但是如果在處理SIGQUIT,來了SIGINT,則首先處理SIGINT,然后接著處理SIGQUIT。

    3.?sa_flags如果取值為0,則表示默認行為。還可以取如下倆值,但是我沒覺得這倆值有啥用。

    SA_NODEFER,如果設置來該標志,則不進行當前處理信號到阻塞

    SA_RESETHAND,如果設置來該標志,則處理完當前信號后,將信號處理函數設置為SIG_DFL行為


    下面單獨來討論一下信號屏蔽,記住是屏蔽,不是消除,就是來了信號,如果當前是block,則先不傳遞給當前進程,但是一旦unblock,則信號會重新到達。

    [cpp]?view plaincopy
  • #include?<signal.h>??
  • #include?<stdio.h>??
  • #include?<unistd.h>??
  • ??
  • ??
  • ??
  • static?void?sig_quit(int);??
  • ??
  • int?main?(void)?{??
  • ????sigset_t?new,?old,?pend;??
  • ??????
  • ????signal(SIGQUIT,?sig_quit);??
  • ??
  • ????sigemptyset(&new);??
  • ????sigaddset(&new,?SIGQUIT);??
  • ????sigprocmask(SIG_BLOCK,?&new,?&old);??
  • ??
  • ????sleep(5);??
  • ??
  • ????printf("SIGQUIT?unblocked\n");??
  • ????sigprocmask(SIG_SETMASK,?&old,?NULL);??
  • ??
  • ????sleep(50);??
  • ????return?1;??
  • }??
  • ??
  • static?void?sig_quit(int?signo)?{??
  • ????printf("catch?SIGQUIT\n");??
  • ????signal(SIGQUIT,?SIG_DFL);??
  • }??

  • gcc -g -o mask mask.c?

    ./mask

    ========這個地方按多次ctrl+\

    SIGQUIT unblocked

    catch SIGQUIT
    Quit (core dumped)

    ======================

    注意觀察運行結果,在sleep的時候,按多次ctrl+\,由于sleep之前block了SIG_QUIT,所以無法獲得SIG_QUIT,但是一旦運行sigprocmask(SIG_SETMASK, &old, NULL);則unblock了SIG_QUIT,則之前發送的SIG_QUIT隨之而來。

    由于信號處理函數中設置了DFL,所以再發送SIG_QUIT,則直接coredump。



    總結

    以上是生活随笔為你收集整理的linux 信号signal和sigaction理解的全部內容,希望文章能夠幫你解決所遇到的問題。

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