UNP學習第五章(二)
一、POSIX信號處理
信號:告知某進程發生了某個事件的通知(軟中斷),通常是異步的。
信號可以:由進程發給另一個進程,由內核發給某個進程。
設置信號處理辦法,有三個選擇:
1.寫一個函數,在信號發生時立即調用。不過SIGKILL和SIGSTOP不能被捕獲。
有些信號如SIGIO、SIGPOLL和SIGURG。
2.設置信號處理辦法為SIG_IGN來忽略,SIGKILL和SIGSTOP不能忽略
3.設置信號處理辦法為SIG_DFL來設置缺省處理。
#include <signal.h> sighandler_t signal(int signum, sighandler_t handler); 返回值:成功返回以前的信號處理配置,出錯返回SIG_ERR
signum:信號名
handler:上面三個的一種,函數名,SIG_IGN或SIG_DFL
對POSIX兼容系統上的信號處理作以下總結:
- 一旦安裝了信號處理程序,便一直安裝著。
- 當一個信號處理程序正在執行時,所遞交的信號是阻塞的。包括在sa_mask中定義的信號。
- 信號在阻塞時生成了多次,解阻塞時只發生一次。
- 用sigprocmask可以選擇性的阻塞和不阻塞一組信號
二、處理SIGCHLD信號
當一個進程終止,如果它有子進程處於僵屍狀態,則所有僵屍子進程的父進程ID均設置為1。
警告:在信號處理程序中調用諸如printf這樣的標準I/O函數是不合適的。
太長了,原諒我看不懂。。。。
三、wait和waitpid函數
#include <sys/wait.h> pid_t wait(int *statloc); pid_t waitpid(pid_t pid, int *statloc, int options); 返回:進程ID0成功,-1出錯
statloc:子進程終止狀態
options:
當服務器創建子進程處理消息後,子進程結束時。會發送SIG_CHILD信號。此時如果有多個進程同時退出,那麽
進程的SIG_CHILD在阻塞時收到,就會只響應一次。
所以需要wait或waipid處理。
1 #include "unp.h" 2 3 void 4 sig_chld(int signo) 5 { 6 pid_t pid; 7 int stat;8 9 while((pid = waitpid(-1, &stat, WHOHANG)) > 0) 10 printf("child %d terminated\n", pid); 11 return; 12 }
我們在網絡編程時可能會遇到的三種情況:
1.當派生子進程時,必須捕獲信號SIGCHLD。
2.當捕獲信號時,必須處理被中斷的系統調用。
3.SIGCHLD的信號處理程序必須正確編寫,應使用函數waitpid以免留下僵屍進程。
四、服務器進程終止
1.在不同主機上啟動服務器和客戶,並在客戶鍵入一行,若正常。服務器回射
2.找到服務器子進程,並殺死該進程。子進程發送FIN給客戶,客戶TCP相應的以ACK響應。
3.信號SIGCHLD發往服務器並正確處理。
4.客戶TCP從服務器TCP接收FIN並以ACK響應。但客戶進程正阻塞在fgets,等待從終端上得到一行。
5.運行netstat觀察客戶套接口狀態
6.再鍵入一行,
7.看不下去了
8。。。。。。
五、SIGPIPE信號
六、服務器主機崩潰
UNP學習第五章(二)