signal(SIGCHLD, SIG_IGN); //忽略SIGCHLD信號,這常用於並發服務器的性能的一個技巧
//服務器進程去wait清理資源。如果將此信號的處理方式設為
//忽略,可讓內核把僵屍子進程轉交給init進程去處理,省去了
//大量僵屍進程占用系統資源。(Linux Only)
if (pid < 0) // error check.
handle_err();
exit (execl(....)); // child process.
else
if (wait(&ret) < 0)
perror(/"wait/"); //parent process
//在這里wait,都會得No Such process的錯誤,
//因為子進程終止后,內核會向父進程發送SIGCHLD
//信號,但是上面已將此信號設為忽略,實質上由
//init來接收此子進程的處理。
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的函數的指針”。