日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

UNIX 進(jìn)程揭秘( 四 )


sean 2934 28850 21:43:05 pts/10:00 ./die2
sean 2935 29340- ?0:00
sunbox$ ps -ef | grep 2934
[1]Exit 199./die2
die2 使用 & 操作符在后臺(tái)運(yùn)行,然后顯示一個(gè)進(jìn)程清單,并且僅顯示正在運(yùn)行的進(jìn)程及其子進(jìn)程 。PID 2934 是父進(jìn)程,PID 2935 是派生 (fork) 并立即終止的進(jìn)程 。盡管子進(jìn)程提前退出,但它仍然在進(jìn)程表中作為失效 (defunct) 進(jìn)程存在,或稱為僵死 (zombie) 進(jìn)程 。當(dāng)父進(jìn)程在 60 秒以后終止時(shí),兩個(gè)進(jìn)程都消失了 。
當(dāng)子進(jìn)程終止時(shí),會(huì)使用一個(gè)名為 SIGCHLD 的信號(hào)來(lái)通知其父進(jìn)程 。該通知的確切機(jī)制現(xiàn)在對(duì)您并不重要 。重要的是父進(jìn)程必須以某種方式確認(rèn)子進(jìn)程的終止 。子進(jìn)程從終止時(shí)起就一直處于僵死狀態(tài),直到父進(jìn)程確認(rèn)該信號(hào)為止 。僵死進(jìn)程不運(yùn)行或消耗 CPU 周期;它只是占用進(jìn)程表空間 。當(dāng)父進(jìn)程終止時(shí),內(nèi)核最終能夠回收未確認(rèn)的子進(jìn)程以及父進(jìn)程 。這意味著可消除僵死進(jìn)程的唯一方法是終止父進(jìn)程 。處理僵死進(jìn)程的最好方法是首先確保它們不會(huì)發(fā)生 。清單 8 中的代碼實(shí)現(xiàn)了一個(gè)處理傳入的 SIGCHLD 信號(hào)的信號(hào)處理程序 。
清單 8. 實(shí)際操作中的信號(hào)處理程序
#include
#include
#include
#include
void sighandler(int sig) {
printf("In signal handler for signal %dn", sig);
/* wait() is the key to acknowledging the SIGCHLD */
wait(0);
}
int main(void) {
int i;
/* Assign a signal handler to SIGCHLD */
sigset(SIGCHLD, &sighandler);
if (!fork()) {
/* Child */
_exit(0);
}
sleep(60);
}
sunbox$ gcc dIE3.c -o die3
sunbox$ ./die3 &
[1] 3116
sunbox$ In signal handler for signal 18
ps -ef | grep 3116
sean 3116 28850 22:37:26 pts/10:00 ./die3
由于使用了 sigset 函數(shù)(它向信號(hào)處理程序分配一個(gè)函數(shù)指針),清單 8 比前一個(gè)示例稍微復(fù)雜一點(diǎn),。每當(dāng)進(jìn)程接收到某個(gè)已處理的信號(hào)時(shí),就會(huì)調(diào)用通過(guò) sigset 分配的函數(shù) 。對(duì)于 SIGCHLD 信號(hào),應(yīng)用程序必須調(diào)用 wait(3c) 函數(shù),以等待子進(jìn)程退出 。由于該進(jìn)程已經(jīng)退出,這相當(dāng)于向內(nèi)核確認(rèn)了子進(jìn)程的終止 。實(shí)際上,父進(jìn)程所做的工作可能不只是確認(rèn)該信息 。它還可能需要清理子進(jìn)程的數(shù)據(jù) 。
在執(zhí)行 die3 以后,代碼檢查了進(jìn)程清單,并干凈地執(zhí)行子進(jìn)程 。然后使用值 18 (SIGCHLD) 來(lái)調(diào)用信號(hào)處理程序,確認(rèn)子進(jìn)程的退出,并且父進(jìn)程返回到 sleep(60) 。
總結(jié)
Unix 進(jìn)程是在某個(gè)進(jìn)程調(diào)用 fork 時(shí)創(chuàng)建的,fork 將正在運(yùn)行的可執(zhí)行進(jìn)程一分為二 。然后該進(jìn)程可以執(zhí)行 exec 系列中的某個(gè)系統(tǒng)調(diào)用,從而將當(dāng)前運(yùn)行的映像替換為新的映像 。
當(dāng)父進(jìn)程終止時(shí),其所有子進(jìn)程將由 PID 為 1 的 init 接納 。如果子進(jìn)程在父進(jìn)程之前終止,則會(huì)向父進(jìn)程發(fā)送一個(gè)信號(hào),然后子進(jìn)程轉(zhuǎn)變?yōu)榻┧罓顟B(tài),直到該信號(hào)得到確認(rèn),或父進(jìn)程被終止 。
【UNIX 進(jìn)程揭秘】現(xiàn)在您已了解了進(jìn)程是如何創(chuàng)建和銷毀的,您已經(jīng)為處理運(yùn)行您系統(tǒng)的進(jìn)程作了更好的準(zhǔn)備,尤其是大量使用多進(jìn)程的系統(tǒng),例如 Apache 。如果您需要執(zhí)行某些故障排除,能夠跟蹤某個(gè)特定進(jìn)程的進(jìn)程樹(shù)還允許您將任何應(yīng)用程序追溯到創(chuàng)建它的進(jìn)程 。

推薦閱讀