linux僵死進程與並發伺服器編程

來源:互聯網
上載者:User

標籤:style   class   blog   c   code   color   

序

僵死(zombie)進程簡而言之就是:子進程退出時,父進程並未對其發出的SIGCHILD訊號進行適當處理,導致子進程停留在僵死狀態等待其父進程為其收屍,這個狀態下的子進程就是僵死進程。

因為並發伺服器常常fork很多子進程,子進程終結之後需要伺服器處理序去wait清理資源。對於某些進程,特別是伺服器處理序往往在請求到來時產生子進程處理請求。如果父進程不等待子進程結束,子進程將成為殭屍進程(zombie)從而佔用系統資源。如果父進程等待子進程結束,將增加父進程的負擔,影響伺服器處理序的並發效能。

尋找所有的僵死進程

 ps -A -o stat,ppid,pid,cmd | grep -e ‘^[Zz]‘

處理僵死進程最簡單的方法忽略SIGCHLD訊號讓系統處理

在Linux下調用signal(SIGCHLD, SIG_IGN),可以簡單地將 SIGCHLD訊號的操作設為SIG_IGN忽略。 這樣可以讓核心把殭屍子進程轉交給init進程去處理,省去了大量殭屍進程佔用系統資源。(Linux Only)

父進程waitpid釋放僵死進程

父進程在fork調用之前調用signal設定SIGCHLD訊號處理函數。SIGCHLD處理函數如下:

void sig_chld(int signo){pid_t pid;int stat;//Unix下如果一個訊號在被阻塞期間產生一次或多次,那麼該訊號被解阻塞之後通常只遞交一次,也就是說Unix訊號預設是不排隊的。while ((pid=waitpid(-1, &stat, WNOHANG)) > 0){pintf("child %d terminated\n", pid);}return;}
通訊注意事項

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. 程式便能知道對端已經關閉.



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.