linux之C編程學習——訊號處理

來源:互聯網
上載者:User

標籤:

  訊號處理是linux程式的一個特色。用訊號處理來類比作業系統的中斷功能。要想使用訊號處理功能,你要做的就是填寫一個訊號處理函數即可。

 1 #include <stdio.h>    2 #include <sys/types.h>    3 #include <stdlib.h>     4 #include <signal.h>     5    6 int flag = 1;     7    8 void func(int sig)       9 {   10     printf("I get a signal!\n");   11     flag = 0;     12 }    13   14 int main()     15 {    16     signal(SIGINT, func);   17     printf("pid:%ld\n",(long)getpid());   18   19     while(flag)  20     pause();   21   22     return 0;    23 }    

執行:

#gcc sig.c -o sig    #./sig    在另一終端:     #kill -INT 333//333是程式列印出的進程號 

  要對一個訊號進行處理,就需要給出此訊號發生時系統所調用的處理函數。可以對一個特定的訊號(除去SIGKILL和SIGSTOP訊號)註冊相應的處理函數。註冊某個訊號的處理函數後,當進程接收到此訊號時,無論進程處於何種狀態,就會停下當前的任務去執行此訊號的處理函數。

1. 註冊訊號函數

#include<signal.h>    void(*signal(int signumber,void ((*func)(int))(int)  

  signumber表示訊號處理函數對應的訊號。func是一個函數指標。此函數有一整型參數,並返回void型。其實func還可以取其他定值如:SIG_IGN,SIG_DFL。SIG_IGN表示:忽略signumber所指出的訊號。SIG_DFL表示表示調用系統預設的處理函數。signal函數的傳回值類型同參數func,是一個指向某個傳回值為空白並帶有一個整型參數的函數指標。其正確傳回值應為上次該訊號的處理函數。錯誤返回SIG_ERR。

signal樣本如下:

 1 #include <stdio.h>   2 #include <sys/types.h>    3 #include <stdlib.h>    4 #include <signal.h>    5  6 void func(int sig)    7 {   8     printf("I get asignal!\n");   9 }   10 11 int main()   12 {    13     charbuffer[100];   14   15    if(signal(SIGINT, func) == SIG_ERR)  16      {  17          printf("signalerror exit now\n");  18          exit(0);  19      }  20      printf("pid:%ld\n",(long)getpid());  21   22    for(;;)  23      {  24          fgets(buffer,sizeof(buffer),stdin);  25          printf("bufferis:%s\n",buffer);  26      }  27      return 0;   28 }   

  通常情況下一個使用者進程需要處理多個訊號。可以在一個程式中註冊多個訊號處理函數。一個訊號可以對應一個處理函數,同時多個訊號可以對應一個處理函數。對於SIGINT訊號 我們可以用ctrl+c或ctrl+z來中斷進程,來執行SIGINT註冊的函數。

2. 進階訊號處理

在linux系統提供了一個功能更強的系統調用。

#include <signal.h>    int sigaction(int signumbet,const structsigaction *act,struct sigaction *oldact)

  此函數除能註冊訊號函數外還提供了更加詳細的資訊,確切瞭解進程接收到訊號,發生的具體細節。struct sigaction的定義如下:

struct sigaction    {         void(*sa_handler)(int);         void(*sa_sigaction)(int,siginfo_t *,void *);         sigset_tsa_mask;         intsa_flags;  }  

sa_flags的取值如下表,取0表示選用所有預設選項。

SA_NOCLDSTOP:用於表示訊號SIGCHLD,當子進程被中斷時,不產生此訊號,若且唯若子進程結束時產生此訊號。

SA_NOCLDWATI:當訊號為SIGCHLD,時可避免子進程僵死。

SA_NODEFER:當訊號處理函數進行中時,不堵塞對於訊號處理函數自身訊號功能。

SA_NOMASK:同SA_NODEFER

SA_ONESHOT:當使用者註冊的訊號處理函數被執行過一次後,該訊號的處理函數被設為系統預設的處理函數。

SA_RESETHAND:同SA_ONESHOT

SA_RESTART:是本來不能重新於啟動並執行系統調用自動重新運行。

SA_SIGINFO:表明訊號處理函數是由SA_SIGACTION指定的,而不是由SA_HANDLER指定的,它將顯示更多的訊號處理函數資訊。

 

其實sinaction完全可以替換signal函數:

 1 #include <stdio.h>    2 #include <sys/types.h>    3 #include <stdlib.h>     4 #include <signal.h>     5      6 void func(int sig)      7 {     8     printf("I get a signal!\n");     9 }    10   11 int main()    12 {   13     char buffer[100];    14   15     struct sigaction act;  16     act.sa_handler=func;  17     sigemptyset(&act.sa_mask);  18     act.sa_flags = 0;  19   20     if(sigaction(SIGINT,&act, NULL) == -1)  21     {  22         printf("sigaction error exit now\n");  23         exit(0);  24     }  25   26     printf("pid:%ld\n",(long)getpid());   27   28     for(;;)  29     {  30         fgets(buffer,sizeof(buffer),stdin);  31         printf("buffer is:%s\n",buffer);  32     }  33   34     return 0;    35 }

 

linux之C編程學習——訊號處理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.