歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux的信號處理和實際使用(結合Redis分析)

最近比較多朋友問我常見的信號和一些Linux信號實際的應用。所以,我簡單總結一下,讓大家對信號有清晰的理解。
 
我自己寫的系統裡面,我是直接參考redis的信號處理機制的。

redis是這樣處理信號的:
 
如果系統支持 HAVE_BACKTRACK,即是:
 
#if defined(__APPLE__) || defined(__linux__) || defined(__sun)
 #define HAVE_BACKTRACE 1
 #endif
 

那麼redis會用sigsegvHandler函數處理SIGSEGV  , SIGBUS , SIGFPE , SIGILL等信號。
 
否則只用sigtermHandler 處理 SIGTERM ,SIGQUIT  。
 
我自己系統是這樣實現的(分析如上):
 
void
 setupSignalHandlers(void){
    struct sigaction act;
   
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    act.sa_handler = sigtermHandler;
    sigaction(SIGTERM , &act , NULL);
    sigaction(SIGQUIT , &act , NULL);
   
 #ifdef HAVE_BACKTRACE
    sigemptyset(&act.sa_mask);
    act.sa_flags = SA_NODEFER|SA_RESETHAND|SA_SIGINFO;
    act.sa_sigaction = sigsegvHandler;
    sigaction(SIGSEGV ,&act , NULL);
    sigaction(SIGBUS  ,&act , NULL);
    sigaction(SIGFPE  ,&act , NULL);
    sigaction(SIGILL  ,&act , NULL);
 #endif /* HAVE_BACKTRACE */
    return;
 }

SIGKILL : 用來立即結束程序的運行. 本信號不能被阻塞, 處理和忽略。

SIGTERM : 有兩個信號可以停止進程:SIGTERM和SIGKILL。 SIGTERM比較友好,進程能捕捉這個信號,根據您的需要來關閉程序。在關閉程序之前,您可以結束打開的記錄文件和完成正在做的任務。在某些情況下,假 如進程正在進行作業而且不能中斷,那麼進程可以忽略這個SIGTERM信號。

SIGINT  : 程序終止(interrupt)信號, 在用戶鍵入INTR字符(通常是Ctrl-C)時發出。

SIGQUIT信號: SIGQUIT 和SIGINT類似, 但由QUIT字符(通常是Ctrl-)來控制. 進程在因收到 SIGQUIT退出時會產生core文件, 在這個意義上類似於一個程序錯誤信號。

SIGSEGV  : 試圖訪問未分配給自己的內存, 或試圖往沒有寫權限的內存地址寫數據

SIGBUS :非法地址, 包括內存地址對齊(alignment)出錯. eg: 訪問一個四個字長的整數, 但其地址不是4的倍數.

SIGFPE :  在發生致命的算術運算錯誤時發出. 不僅包括浮點運算錯誤, 還包括溢出及除數為0等其它所有的算術的錯誤.

SIGILL :  執行了非法指令. 通常是因為可執行文件本身出現錯誤, 或者試圖執行數據段. 堆棧溢出時也有可能產生這個信號.

(不得不說的是,redis的信號處理機制。非常漂亮。在程序出現錯誤的時候,可以打印出和valgrind一樣有用的信息。不知道大家是怎樣想的。反正我的項目如果C代碼過3K。我都會加入這個機制的。)

Redis 的詳細介紹:請點這裡
Redis 的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved