一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

《UNIX環(huán)境高級編程》的筆記——wait&waitpid

 幸福的樂土 2012-02-15
wait&waitpid
進(jìn)程結(jié)束,無論是否正常中止,內(nèi)核都會給它的父進(jìn)程發(fā)送一個SIGCHILD的通知。(雖然這個老爸一點(diǎn)都不計劃生育也不在乎孩子,但是孩子死了總得通知他一下吧)。顯然這個通知是異步的,某天老爸下班回家可能就在郵箱里看到它若干孩子的死亡證明了。父進(jìn)程是比較不負(fù)責(zé)任的,所以它可能隨手把這個死亡證明扔了(ignore it),或者如果他比較愛那個孩子的話,就給它辦個葬禮(signal handler)。吶,都說了這個老爸是不負(fù)責(zé)任的,所以default方式就是扔了。
作為一個進(jìn)程,它調(diào)用wait或者waitpid的話會
1.block。 如果它所有的子進(jìn)程都在運(yùn)行(這里是否應(yīng)該理解為這些子進(jìn)程沒有死掉)
2.帶著某個子進(jìn)程的中止?fàn)顟B(tài)立即返回。如果有一個子進(jìn)程已經(jīng)中止并等待它父進(jìn)程來存取它的中止?fàn)顟B(tài)。
3,如果它已經(jīng)沒有子進(jìn)程了,就以錯誤退出。
wait會使調(diào)用者block,直到它有某個子進(jìn)程中止為止。而waitpid的第三個參數(shù)可使調(diào)用者不中止。
 
1、下面部分來自:http:///blog/65

第八章進(jìn)程控制,其中講到了僵死進(jìn)程,它的定義是這樣的:
        在 UNIX 術(shù)語中,一個已經(jīng)終止,但其父進(jìn)程尚未對其進(jìn)行善后處理(獲取終止進(jìn)程的有關(guān)信息,釋放它仍占 有 的資源)的進(jìn)程被稱為僵死進(jìn)程( zombie )。

如果編寫一個長期運(yùn)行的程序,它調(diào)用 fork 產(chǎn)生了很多子進(jìn)程,那么除非父進(jìn)程等待取得子進(jìn)程的終止?fàn)顟B(tài),否則這些子進(jìn)程終止后就會變成僵死進(jìn)程。

我創(chuàng)建了一個子進(jìn)程來做這些事情,和父進(jìn)程并行運(yùn)行,從而不引起服務(wù)中斷。代碼類似于:

...
if ((pid = fork()) == 0)
{
    /* do some thing */
  
    exit(0);
}
...

這樣子進(jìn)程調(diào)用 exit() 進(jìn)入終止?fàn)顟B(tài)后,父進(jìn)程沒有調(diào)用 wait() / waitpid() 函數(shù),也沒有顯式忽略 SIGCHLD 信號,進(jìn)程就會進(jìn)入僵死狀態(tài)。我在程序運(yùn)行一段時間后,使用命令

ps -ef | grep a.out

果然發(fā)現(xiàn)了很多僵死進(jìn)程。僵死進(jìn)程消耗很小的計算機(jī)資源,但是 Linux 系統(tǒng)對運(yùn)行的進(jìn)程數(shù)量有限制,如果產(chǎn)生過多的僵尸進(jìn)程占用了可用的進(jìn)程號,將會導(dǎo)致新的進(jìn)程無法生成。但程序如果使用 wait() / waitpod() 阻塞等待的話,已經(jīng)失去創(chuàng)建子進(jìn)程的意義。

解決辦法一:程序在進(jìn)入終止?fàn)顟B(tài)時會向父進(jìn)程發(fā)送 SIGCHLD 信號,在 linux 上,如果在程序開始運(yùn)行時顯式忽略該信號可以避免僵死進(jìn)程的產(chǎn)生,代碼如下:

if (signal(SIGCHLD, SIG_IGN) == SIG_ERR)
{
    fputs("Cannot catch SIGCHLD\n", stderr);
    exit(1);
}

這樣做并不是一個標(biāo)準(zhǔn)的做法,因為在某些 UNIX 操作系統(tǒng)上,忽略該信號并不能避免僵死進(jìn)程的產(chǎn)生。

解決辦法二:更好的做法是調(diào)用 signal() 函數(shù)接管 SIGCHLD 信號,父進(jìn)程收到此信號后,執(zhí)行 waitpid() 函數(shù)為子進(jìn)程收尸。代碼如下:

static void process_wait(int sig)
{
    while (waitpid(-1, NULL, WNOHANG) > 0)
        ;
}
...
if (signal(SIGCHLD, process_wait) == SIG_ERR)
{
    fputs("Cannot catch SIGCHLD\n", stderr);
    exit(1);
}
...
waitpid() 函數(shù)在指定 WNOHANG 參數(shù)時,并不會阻塞進(jìn)程運(yùn)行。此時 waitpid() 作用為獲得進(jìn)程的運(yùn)行信息,當(dāng)子進(jìn)程沒有結(jié)束時返回值為 0, 在已經(jīng)結(jié)束則返回值為子進(jìn)程 ID.
 
2、下面的部分是轉(zhuǎn)來的,源網(wǎng)址http://doc./53457.html
查看linux源代碼 unistd.h 我們會發(fā)現(xiàn),其實 wait 就是經(jīng)過包裝的 waitpid:
staticinlinepid_twait(int*wait_stat)
{
    returnwaitpid(-1,wait_stat,0);
}
waitpid的返回值比wait稍微復(fù)雜一些,一共有3種情況:
1. 當(dāng)正常返回的時候,waitpid返回收集到的子進(jìn)程的進(jìn)程ID;
2. 如果設(shè)置了選項WNOHANG,而調(diào)用中waitpid發(fā)現(xiàn)沒有已退出的子進(jìn)程可收集,則返回0;
3. 如果調(diào)用中出錯,則返回-1,這時errno會被設(shè)置成相應(yīng)的值以指示錯誤所在;
當(dāng)pid所指示的子進(jìn)程不存在,或此進(jìn)程存在,但不是調(diào)用進(jìn)程的子進(jìn)程,waitpid就會出錯返回,這時errno被設(shè)置為ECHILD;
下面看一個簡單的例子:
下載:waitpid.c
/* waitpid.c */
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdio.h>
int main()
{
   pid_t pc,pr;
   pc=fork();
   if (pc<0)/* fork錯誤*/
   {
       printf("fork error\n");
       exit(1);
   }
   else if(pc==0)/*在子進(jìn)程中*/
   {
       sleep(10);
       exit(0);
   }
   else
   {
       do {/* 使用了WNOHANG參數(shù),waitpid不會在這里等待 */
           pr=waitpid(pc,NULL,WNOHANG);
           if (pr==0)
           {
               printf("No child exit\n");
               sleep(1);
           }
          }while (pr==0);
       if (pr==pc)
           printf("successfully get child %d\n",pr);
       else
           printf("wait child error\n");
   }
   return 0;
}
編譯并運(yùn)行:
$ gcc -o waitpid waitpid.c
$ ./waitpid
No child exit
No child exit
No child exit
No child exit
No child exit
No child exit
No child exit
No child exit
No child exit
No child exit
successfully get child 4607
父進(jìn)程經(jīng)過10次失敗的嘗試之后,終于收集到了退出的子進(jìn)程。父進(jìn)程和子進(jìn)程分別睡眠了10秒鐘和1秒鐘,代表它們分別作了10秒鐘和1秒鐘的工作。父子進(jìn)程都有工作要做,父進(jìn)程利用工作的簡短間歇察看子進(jìn)程的是否退出,如退出就收集它。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    最新午夜福利视频偷拍| 国产传媒中文字幕东京热| 国产精品超碰在线观看| 久久中文字幕中文字幕中文| 老司机精品视频在线免费看 | 欧美三级不卡在线观线看| 亚洲另类欧美综合日韩精品| 日韩成人动画在线观看| 欧美一级不卡视频在线观看| 久久女同精品一区二区| 欧美三级大黄片免费看| 少妇视频一区二区三区| 东京热男人的天堂久久综合| 亚洲精品有码中文字幕在线观看 | 在线视频三区日本精品| 欧美色婷婷综合狠狠爱| 亚洲做性视频在线播放| 插进她的身体里在线观看骚| 熟女少妇一区二区三区蜜桃| 欧美人妻一区二区三区| 国产精品一区二区丝袜| 国产精品一区二区香蕉视频| 中日韩美女黄色一级片| 在线亚洲成人中文字幕高清| 国产中文字幕一区二区| 欧美一级特黄特色大色大片| 一区二区在线激情视频| 中文字幕欧美视频二区| 久久国产成人精品国产成人亚洲| 午夜精品国产一区在线观看| 色综合久久中文综合网| 乱女午夜精品一区二区三区| 免费精品一区二区三区| 黄片免费观看一区二区| 黄男女激情一区二区三区| 亚洲丁香婷婷久久一区| 中文字幕欧美精品人妻一区| 亚洲熟女精品一区二区成人| 亚洲一区二区三区av高清| 伊人天堂午夜精品草草网| 免费一区二区三区少妇|