SIGCHLD信號與SIG_IGN處理的使用

轉自:
1) http://blog.csdn.net/liuchao1986105/article/details/6440896
2) http://blog.csdn.net/u013246898/article/details/52985739

1)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下必須顯式等待子進程結束才能釋放殭屍進程。


2)我們調用fork函數派生一個子進程後,當子進程快要結束,會向父進程發送一個SIGCHLD信號,告訴父進程我快結束,趕快調用wait函數,來回收子進程的退出狀態和其他信息。 
這就是一種我們通常來預發僵屍進程產出的方法,在父進程接收到SIGCHLD信號後,將默認行爲改爲wait來回收子進程的信息。如果父進程沒有調用wait函數,子進程先於父進程退出,則子進程將成爲殭屍進程。 
但是wait函數需要阻塞父進程直到子進程結束爲止,對於併發要求較高的併發服務器,可能就不是很適用。 
這裏就引出第二種解決殭屍進程的方法,將殭屍進程交給init進程來領養,回收子進程退出狀態和其他信息。當我們忽略SIGCHLD信號,內核將把殭屍進程交由init進程去處理,能夠省去大量殭屍進程佔用系統資源。 

即調用: 
signal(SIGCHLD, SIG_IGN) 



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