========================================================
一般當(dāng)一個(gè)進(jìn)程終止后都會(huì)發(fā)送SIGCHLD信號(hào)給它的父進(jìn)程,,并由此變?yōu)榻┧肋M(jìn)程直到父進(jìn)程接收了其狀態(tài)報(bào)告其資源才會(huì)被系統(tǒng)釋放,;
處理方法有3種: 1. 當(dāng)子進(jìn)程終止時(shí)父進(jìn)程接收SIGCHLD信號(hào)并調(diào)用waitpid()函數(shù)接收其狀態(tài)報(bào)告,最好用sigaction(),signal()不可靠; 2. 通過函數(shù)sigaction指明標(biāo)志SA_NOCLDWAIT來指定信號(hào)SIGCHLD的動(dòng)作,,這使得內(nèi)核在調(diào)用者的子進(jìn)程終止時(shí)不創(chuàng)建僵死進(jìn)程,。 3. 二次fork調(diào)用; ================================================================================================================
引出:
fork之后子進(jìn)程繼承父進(jìn)程的各種變量,、文件描述符,、會(huì)話、進(jìn)程組等,。(簡(jiǎn)單的復(fù)制內(nèi)存,??)
1. 父進(jìn)程不等待子進(jìn)程結(jié)束的處理方式:
signal(SIGCHLD,SIG_IGN)
忽略SIGCHLD信號(hào),,這常用于并發(fā)服務(wù)器的性能的一個(gè)技巧,,因?yàn)椴l(fā)服務(wù)器常常fork很多子進(jìn)程,子進(jìn)程終結(jié)之后需要,,服務(wù)器進(jìn)程去wait清理資源,。
如果將此信號(hào)的處理方式設(shè)為忽略,可讓內(nèi)核把僵尸子進(jìn)程轉(zhuǎn)交給init進(jìn)程去處理,,省去了大量僵尸進(jìn)程占用系統(tǒng)資源,。(Linux Only) 注意:編寫守護(hù)進(jìn)程時(shí),即使fork兩次,,新進(jìn)程由init接管,,不進(jìn)行signal(SIGCHLD,SIG_IGN)操作,也會(huì)產(chǎn)生僵尸進(jìn)程,。
2.父進(jìn)程等待子進(jìn)程結(jié)束的處理方式:
等待單一進(jìn)程結(jié)束:
pid = fork(); //生成一個(gè)子進(jìn)程
if (pid < 0) // error check. handle_err(); if (pid == 0)
exit (execl(....)); // child process. else if (wait(&ret) < 0) perror("wait"); //parent process 等待多個(gè)進(jìn)程:主進(jìn)程中加入信號(hào)處理函數(shù)Proc_CHLD
signal(SIG_CHLD, Proc_CHLD);
void Proc_CHLD(int SIGNO) { int pid = -1; int stat; while(pid=waitpid(0, &stat, WHNONG); } |
|