《unix環境高級編程》-10.信號-讀書筆記

一、基本概念

1、信號是軟件中斷。信號提供了一種異步處理事件的方法。

2、每個信號都有一個名字:這些名字都以SIG開頭。

    例如: SIGABRT是夭折信號,調用abort函數;SIGALRM是鬧鐘信號,當由alarm函數設置的計時器超時後產生此信號;

3、Linux支持31種不同的信號;但是同時支持由應用程序額外定義的信號,將其作爲實時擴展。

4、頭文件爲: <signal.h>

5、不存在編號爲0的信號,kill函數使用編號爲0的信號作爲試探進程時候存在的作用。

7、SIGINT:  Ctrl+C鍵通常產生中斷信號(SIGINT),這是停止一個已失去控制的程序的方法。

8、SIGSEGV:   硬件異常產生信號:除數爲0、無效的內存引用等,這些由硬件檢測到,產生SIGSEGV信號

9、SIGURG:    網絡連接傳來帶外數據時

10、SIGPIPE:    管道讀進程終止後,進程寫此管道時產生,SOCK_STREAM類型的socket關閉時也會產生

11、有兩類不能忽略和捕捉的信號:

    SIGKILL:    

    SIGSTOP:  

    不能忽略的原因是: 它們向超級用戶提供了使進程終止或停止的可靠方法

    

12、捕捉信號: 要通知內核在某種信號發生時調用一個用戶函數,在用戶函數中,可執行用戶希望對這種事件進行處理。  

例如:

     如果捕捉到一個SIGCHLD信號,則表示一個子進程已經終止,所以此信號的捕捉函數可以調用waitpid以取得該子進程的進程ID以及它的的終止狀態。


二、信號 種類:

1、重要摘抄:

SIGINT:   當用戶按中斷鍵(一般採用DELETE或Ctrl+C)時,終端驅動程序產生此信號並送至前臺進程組的每一個進程。當一個進程在運行時失控,特別是產生大量輸出時,常用此信號終止它。

SIGTERM:   由kill命令發送的系統默認終止信號

SIGQUIT: 當用戶在終端上按退出鍵(一般採用Ctrl+\)時,產生此信號,並送至前臺進程組中的所有進程。此信號不僅會終止前臺進程組,同時還會產生一個core文件。

SIGKILL:    這是兩個不能忽略和捕捉的信號之一

SIGSTOP:    這是兩個不能忽略和捕捉的信號之一:這是一個作業控制信號,用於停止一個進程。

SIGCHLD:    當一個進程終止或者停止時,將SIGCHLD信號發送給其父進程,按系統默認,將忽略此信號。如果父進程希望被告知其子進程的這種狀態改變,則應該捕捉此信號。信號捕捉函數中通常要調用一種waitpid函數以取得子進程ID和其終止狀態。

SIGHUP:    如果終端接口檢測到一個鏈接斷開,則將此信號發送給該終端相關的控制進程(會話首進程)。


2、所有信號:

 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL

 5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE

 9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2

13) SIGPIPE     14) SIGALRM     15) SIGTERM     16) SIGSTKFLT

17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP

21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU

25) SIGXFSZ     26) SIGVTALRM   27) SIGPROF     28) SIGWINCH

29) SIGIO       30) SIGPWR      31) SIGSYS      34) SIGRTMIN

35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3  38) SIGRTMIN+4

39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8

43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12

47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14

51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10

55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7  58) SIGRTMAX-6

59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2

63) SIGRTMAX-1  64) SIGRTMAX



三、signal函數:信號處理程序、信號捕捉函數


#include  <signal.h>

void  (*signal(int signo, void (*func)(int) ) )(int)

若出錯返回SIG_ERR

注:因爲signal的語義與實現有關,所以最好使用sigaction函數代替signal函數。


signo:


func的值:(1) 常量SIG_IGN、常量SIG_DEL (2)當捕捉到此信號時要調用的函數的地址。


如果指定SIG_IGN: 表示向內核忽略此信號

如果指定SIG_DEL: 表示捕捉到此信號時採取系統默認動作



四、測試signal函數

程序可運行:

#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>

pthread_mutex_t g_mut;
pthread_cond_t g_cond;
std::string msg;


void sig_capture( int signo ){
  pthread_mutex_lock ( &g_mut );
  switch( signo ){
  case SIGTERM:
    printf("DEBUG: now received SIGTERM(\n");
    msg = "SIGTERM";
    break;
  case SIGQUIT:
    printf("DEBUG: now received SIGQUIT\n");
    msg = "SIGQUIT";
    break;
  case SIGINT:
    msg = "SIGINT";
    printf("DEBUG: now received SIGINT\n");
    break;
  default:
    printf("DBEUG: can't identy this signal\n");
}
  pthread_mutex_unlock ( &g_mut );
  pthread_cond_signal( &g_cond );
}

int main ( int argc, char *argv[] ){

  pthread_mutex_init ( &g_mut, NULL );
  pthread_cond_init ( &g_cond, NULL );

  if ( signal( SIGTERM, sig_capture ) == SIG_ERR ){
    printf("DEBUG: can't catch signal( SIGTERM )\n");
    exit(100);
  }
  if ( signal( SIGQUIT, sig_capture ) == SIG_ERR ){
    printf("DEBUG: can't catch signal( SIGQUIT )\n");
    exit(200);
  }
  if ( signal( SIGINT, sig_capture ) == SIG_ERR ){
    printf("DEBUG: can't catch signal( SIGINT )\n");
    exit(300);
  }




  pthread_mutex_lock ( &g_mut );
  while( msg.empty() ){
    printf("DEBUG: now wait signal...\n");
    pthread_cond_wait ( &g_cond, &g_mut );
  }
  pthread_mutex_unlock( &g_mut );

  printf("DEBUG: now string: %s\n", msg.c_str());

  return 0;
}










































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