unp筆記二 多進程服務器
listenfd=socket(...)
bind(listenfd,..)
listen(listenfd,..)
signal(SIGCHLD,sig_chld) //特意加上處理僵死進程,請看2
for(;;){
connfd=accept(listenfd,..) //在沒有新的連接來到時,父進程阻塞在此
if(fork()==0){
close(listenfd) //子進程只負責連接,必須關了監聽套接字
doit(connfd)
close(connfd)
exit(0) //子進程結束前,關了connfd
}
close(connfd) //連接套接字有子進程負責,父進程關了它
}
服務器子進程終止時,給父進程發送一個SIGCHLD信號
SIGCHLD信號是由內核在任何一個進程終止時發給它的父進程的一個信號 內核發送給進程
所以我們在上面的僞代碼上加上SIGCHLD處理
這裏我們關注兩點,1、同時存在多個僵死子進程的情況,如何一個在處理一個信號的情況下,解決所有殘餘的僵死進程
SIGCHLD是不可靠信號,不排隊,處理方法是在一個循環內使用WAITPID 注意加參數WNOHANG
進程在accept阻塞時收到信號,如果內核無法自動重啓ACCEPT,則accept返回EINTR錯誤,我們只需要自己重啓ACCEPT就行,在代碼中查看errno==EINTR,然後重新accept;
實驗表明linux會自己重啓該系統調用,我們就可以不擔心這個問題,但是爲了我們的代碼在其他UNIX的操作系統也能很好地執行,最好把這個問題處理,就幾行代碼的事。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.