signal(SIGCHLD, SIG_IGN)和signal(SIGPIPE, SIG_IGN);


signal(SIGCHLD, SIG_IGN); //忽略SIGCHLD信號,這常用於並發服務器的性能的一個技巧
//因為並發服務器常常fork很多子進程,子進程終結之后需要
//服務器進程去wait清理資源。如果將此信號的處理方式設為
//忽略,可讓內核把僵屍子進程轉交給init進程去處理,省去了
//大量僵屍進程占用系統資源。(Linux Only)

 

some code();

 

pid = fork(); //生成一個子進程
if (pid < 0) // error check.
handle_err();

 

if (pid == 0)
exit (execl(....)); // child process.
else
if (wait(&ret) < 0)
perror(/"wait/"); //parent process
//在這里wait,都會得No Such process的錯誤,
//因為子進程終止后,內核會向父進程發送SIGCHLD
//信號,但是上面已將此信號設為忽略,實質上由
//init來接收此子進程的處理。
對於某些進程,特別是服務器進程往往在請求到來時生成子進程處理請求。如果父進程不等待子進程結束,子進程將成為僵屍進程(zombie)從而占用系統資源。如果父進程等待子進程結束,將增加父進程的負擔,影響服務器進程的並發性能。在Linux下可以簡單地將 SIGCHLD信號的操作設為SIG_IGN。

signal(SIGCHLD,SIG_IGN);

這樣,內核在子進程結束時不會產生僵屍進程。這一點與BSD4不同,BSD4下必須顯式等待子進程結束才能釋放僵屍進程。

http://blog.csdn.net/liuchao1986105/article/details/6440896

 signal(SIGPIPE, SIG_IGN);

TCP是全雙工的信道, 可以看作兩條單工信道, TCP連接兩端的兩個端點各負責一條. 當對端調用close時, 雖然本意是關閉整個兩條信道, 

但本端只是收到FIN包. 按照TCP協議的語義, 表示對端只是關閉了其所負責的那一條單工信道, 仍然可以繼續接收數據. 也就是說, 因為TCP協議的限制, 一個端點無法獲知對端的socket是調用了close還是shutdown. 對一個已經收到FIN包的socket調用read方法, 如果接收緩沖已空, 則返回0, 這就是常說的表示連接關閉. 但第一次對其調用write方法時, 如果發送緩沖沒問題, 會返回正確寫入(發送). 但發送的報文會導致對端發送RST報文, 因為對端的socket已經調用了close, 完全關閉, 既不發送, 也不接收數據. 所以, 第二次調用write方法(假設在收到RST之后), 會生成SIGPIPE信號, 導致進程退出. 為了避免進程退出, 可以捕獲SIGPIPE信號, 或者忽略它, 給它設置SIG_IGN信號處理函數: signal(SIGPIPE, SIG_IGN); 這樣, 第二次調用write方法時, 會返回-1, 同時errno置為SIGPIPE. 程序便能知道對端已經關閉. http://blog.csdn.net/xinguan1267/article/details/17357093

SIGHCLD
是unix的一種信號。
SIGCHLD信號是子進程結束時,向內核發送的信號。
無論進程是正常終止,還是不正常終止,都會向內核發送SIGCHLD信號。
如果父進程不等待子進程結束,子進程將有可能成為僵屍進程(zombie)從而占用系統資源。
因此需要對SIGCHLD信號做出處理,回收僵屍進程的資源,避免造成不必要的資源浪費。
可以用如下語句:
signal(SIGCHLD,(void *)handle);
handle此處代表一個處理 SIGCHLD信號,引起的函數。
但是在一些並發性特別高的服務器端,有時候又需要對此信號進行忽略。因為,每一個子進程終止時都會向內核發送此信號,如果並發性特別多,將影響服務器處理速率。
可以用如下語句
signal(SIGCHLD,SIG_IGN );

#define SIG_ERR (void (*) ())-1

#define SIG_DFL (void (*) ())0

#define SIG_IGN (void (*) ())1

signal.h中的宏定義SIG_DFL及SIG_IGN

SIG_DFL,SIG_IGN 分別表示無返回值的函數指針,指針值分別是0和1,這兩個指針值邏輯上講是實際程序中不可能出現的函數地址值。

SIG_DFL:默認信號處理程序

SIG_IGN:忽略信號的處理程序

下面是一個指針值測試實例:

復制代碼
#include <stdio.h>
#define SIG_DFL ((void(*)(int))0)
#define SIG_IGN ((void(*)(int))1)

int main() {
    int a = (int) SIG_DFL;
    int b = (int) SIG_IGN;

    printf("a = %d/n", a);  //0
    printf("b = %d/n", b);  //1

    return 0;
}
復制代碼

注:(void(*)())0表示將常數0轉型為“指向返回值為void的函數的指針”。

 轉載自:http://www.cnblogs.com/liulipeng/p/3555450.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM