信號的捕捉

1、如何實現信號的捕捉

   wKioL1eF-y_QX9riAAIHQEL41zk594.png

2、sigaction函數

  include<signal.h>

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

  sigaction函數可以讀取和修改與指定信號相關聯的處理動作。調用成功返回0,出錯返回-1.

  signo是指定信號的編號;若act指針非空,則通過act修改該信號的處理動作;若oact指針非空,則通過oact傳出該信號原來的處理動作。

3、pause函數

    include<unistd.h>

    int pause(void)

   pause函數使調用進程掛起直到有信號遞達,若信號處理動作是默認動作,則終止進程, pause函數不返回;若處理動作是忽略,則進程繼續處於掛起狀態,pause函數不返回;若處理動作是捕捉,則調用信號處理函數之後,pause返回-1,errno設置爲EINTR(被信號中斷), 所以pause只有出錯才返回。

4、volatile限定符

#include<stdio.h>

volatile int flag=0; 
void handler(int sig)
{
 printf("get a sig, %d\n",sig);
 flag=1;
}

int main()
{
 signal(2,handler);
 while(!flag);
 return 0;
}

wKioL1eGa-vDwsDKAAAaeH1jyok128.png

wKioL1eGa-zCZu6TAAAW6bVNCIg979.png

由此看出volatile限定符是防止編譯器對變量的優化,上述例子把flag改爲1,進入while循環才退出

但是要是對上述代碼優化,結果就會變成死循環:

#include<stdio.h>

int flag=0;
void handler(int sig)
{
 printf("get a sig, %d\n",sig);
 flag=1;
}

int main()
{
 signal(2,handler);
 while(!flag);
 return 0;
}

wKiom1eGbiniipfBAAAk2Kwvgpc635.png

wKioL1eGbiqh1JkgAAAW632LUJw517.png

5、my_sleep

#include<stdio.h>
#include<signal.h>
#include<unistd.h>

void handler(int sig)
{
}

unsigned int my_sleep(unsigned int _timeout)
{
 struct sigaction act, oact;
 act.sa_handler=handler;
 sigemptyset(&act.sa_mask);
 act.sa_flags=0;

 sigaction(SIGALRM,&act,&oact);
 alarm(_timeout);
 pause();
 unsigned int remain=alarm(0);

}

int main()
{
 while(1){
  my_sleep(1);
  printf("I use my sleep...\n");
 }
}

sleep就是什麼都不幹,只是捕捉該信號處理函數(自定義信號處理函數),但是捕捉後什麼都不做


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章