• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            旅途

            如果想飛得高,就該把地平線忘掉

            僵尸進(jìn)程的產(chǎn)生和避免

            ?? 在fork()/execve()過(guò)程中,假設(shè)子進(jìn)程結(jié)束時(shí)父進(jìn)程仍存在,而父進(jìn)程fork()之前既沒(méi)安裝SIGCHLD信號(hào)處理函數(shù)調(diào)用 waitpid()等待子進(jìn)程結(jié)束,又沒(méi)有顯式忽略該信號(hào),則子進(jìn)程成為僵尸進(jìn)程,無(wú)法正常結(jié)束,此時(shí)即使是root身份kill -9也不能殺死僵尸進(jìn)程。補(bǔ)救辦法是殺死僵尸進(jìn)程的父進(jìn)程(僵尸進(jìn)程的父進(jìn)程必然存在),僵尸進(jìn)程成為”孤兒進(jìn)程”,過(guò)繼給1號(hào)進(jìn)程init,init始 終會(huì)負(fù)責(zé)清理僵尸進(jìn)程。

            產(chǎn)生原因:
            1.在子進(jìn)程終止后到父進(jìn)程調(diào)用wait()前的時(shí)間里,子進(jìn)程被稱(chēng)為zombie。
            2.網(wǎng)絡(luò)原因有時(shí)會(huì)引起僵死進(jìn)程。

            解決方法:
            1.設(shè)置SIGCLD信號(hào)為SIG_IGN,系統(tǒng)將不產(chǎn)生僵死進(jìn)程。
            2.用兩次fork(),而且使緊跟的子進(jìn)程直接退出,是的孫子進(jìn)程成為孤兒進(jìn)程,從而init進(jìn)程將負(fù)責(zé)清除這個(gè)孤兒進(jìn)程。

            wait的函數(shù)原型是:
              
              #include /* 提供類(lèi)型pid_t的定義 */
              #include
               pid_t wait(int *status)
              
              進(jìn)程一旦調(diào)用了wait,就立即阻塞自己,由wait自動(dòng)分析是否當(dāng)前進(jìn)程的某個(gè)子進(jìn)程已經(jīng)退出,如果讓它找到了這樣一個(gè)已經(jīng)變成僵尸的子進(jìn)程, wait就會(huì)收集這個(gè)子進(jìn)程的信息,并把它徹底銷(xiāo)毀后返回;如果沒(méi)有找到這樣一個(gè)子進(jìn)程,wait就會(huì)一直阻塞在這里,直到有一個(gè)出現(xiàn)為止。
              
              參數(shù)status用來(lái)保存被收集進(jìn)程退出時(shí)的一些狀態(tài),它是一個(gè)指向int類(lèi)型的指針。但如果我們對(duì)這個(gè)子進(jìn)程是如何死掉的毫不在意,只想把這個(gè)僵尸進(jìn)程消滅掉,(事實(shí)上絕大多數(shù)情況下,我們都會(huì)這樣想),我們就可以設(shè)定這個(gè)參數(shù)為NULL,就象下面這樣:
              
              pid = wait(NULL);
              
              如果成功,wait會(huì)返回被收集的子進(jìn)程的進(jìn)程ID,如果調(diào)用進(jìn)程沒(méi)有子進(jìn)程,調(diào)用就會(huì)失敗,此時(shí)wait返回-1,同時(shí)errno被置為ECHILD。
             

            waitpid的函數(shù)原型是:


              簡(jiǎn)介
              waitpid系統(tǒng)調(diào)用在Linux函數(shù)庫(kù)中的原型是:
              
              #include /* 提供類(lèi)型pid_t的定義 */
              #include
              pid_t waitpid(pid_t pid,int *status,int options)

            從本質(zhì)上講,系統(tǒng)調(diào)用waitpid和wait的作用是完全相同的,但waitpid多出了兩個(gè)可由用戶(hù)控制的參數(shù)pid和options,從而為我們編程提供了另一種更靈活的方式。下面我們就來(lái)詳細(xì)介紹一下這兩個(gè)參數(shù):
              
              ● pid
              
              從參數(shù)的名字pid和類(lèi)型pid_t中就可以看出,這里需要的是一個(gè)進(jìn)程ID。但當(dāng)pid取不同的值時(shí),在這里有不同的意義。
              
              pid>0時(shí),只等待進(jìn)程ID等于pid的子進(jìn)程,不管其它已經(jīng)有多少子進(jìn)程運(yùn)行結(jié)束退出了,只要指定的子進(jìn)程還沒(méi)有結(jié)束,waitpid就會(huì)一直等下去。
              
              pid=-1時(shí),等待任何一個(gè)子進(jìn)程退出,沒(méi)有任何限制,此時(shí)waitpid和wait的作用一模一樣。
              
              pid=0時(shí),等待同一個(gè)進(jìn)程組中的任何子進(jìn)程,如果子進(jìn)程已經(jīng)加入了別的進(jìn)程組,waitpid不會(huì)對(duì)它做任何理睬。
              
              pid<-1時(shí),等待一個(gè)指定進(jìn)程組中的任何子進(jìn)程,這個(gè)進(jìn)程組的ID等于pid的絕對(duì)值。

              ● options

              options提供了一些額外的選項(xiàng)來(lái)控制waitpid,目前在Linux中只支持WNOHANG和WUNTRACED兩個(gè)選項(xiàng),這是兩個(gè)常數(shù),可以用"|"運(yùn)算符把它們連接起來(lái)使用,比如:


              ret=waitpid(-1,NULL,WNOHANG | WUNTRACED);


              如果我們不想使用它們,也可以把options設(shè)為0,如:


              ret=waitpid(-1,NULL,0);
              
              如果使用了WNOHANG參數(shù)調(diào)用waitpid,即使沒(méi)有子進(jìn)程退出,它也會(huì)立即返回,不會(huì)像wait那樣永遠(yuǎn)等下去。
              
              而WUNTRACED參數(shù),由于涉及到一些跟蹤調(diào)試方面的知識(shí),加之極少用到,這里就不多費(fèi)筆墨了,有興趣的讀者可以自行查閱相關(guān)材料。
              
              看到這里,聰明的讀者可能已經(jīng)看出端倪了--wait不就是經(jīng)過(guò)包裝的waitpid嗎?沒(méi)錯(cuò),察看<內(nèi)核源碼目錄>/include/unistd.h文件349-352行就會(huì)發(fā)現(xiàn)以下程序段:
              
              static inline pid_t wait(int * wait_stat)
              {
               return waitpid(-1,wait_stat,0);
              }
              

              返回值和錯(cuò)誤
              
              waitpid的返回值比wait稍微復(fù)雜一些,一共有3種情況:
              
              ● 當(dāng)正常返回的時(shí)候,waitpid返回收集到的子進(jìn)程的進(jìn)程ID;
              
              ● 如果設(shè)置了選項(xiàng)WNOHANG,而調(diào)用中waitpid發(fā)現(xiàn)沒(méi)有已退出的子進(jìn)程可收集,則返回0;
              
              ● 如果調(diào)用中出錯(cuò),則返回-1,這時(shí)errno會(huì)被設(shè)置成相應(yīng)的值以指示錯(cuò)誤所在;
              
              當(dāng)pid所指示的子進(jìn)程不存在,或此進(jìn)程存在,但不是調(diào)用進(jìn)程的子進(jìn)程,waitpid就會(huì)出錯(cuò)返回,這時(shí)errno被設(shè)置為ECHILD

            其它:

            調(diào)用 wait&waitpid 來(lái)處理終止的子進(jìn)程:

            pid_t wait(int* statloc);
            pid_t waitpid(pid_t pid,
            int*statloc, int options);

            兩個(gè)函數(shù)都返回兩個(gè)值:函數(shù)的返回值和終止的子進(jìn)程ID,而子進(jìn)程終止的狀態(tài)則是通過(guò)statloc指針?lè)祷氐摹?br />

            ???? wait&waitpid 的區(qū)別是顯而易見(jiàn)的,wait等待第一個(gè)終止的子進(jìn)程,而waitpid則可以指定等待特定的子進(jìn)程。這樣的區(qū)別可能會(huì)在下面這種情況時(shí)表現(xiàn)得更加明顯:
            ???????? 當(dāng)同時(shí)有5個(gè)客戶(hù)連上服務(wù)器,也就是說(shuō)有五個(gè)子進(jìn)程分別對(duì)應(yīng)了5個(gè)客戶(hù),此時(shí),五個(gè)客戶(hù)幾乎在同時(shí)請(qǐng)求終止,這樣一來(lái),幾乎同時(shí),五個(gè)FIN發(fā)向服務(wù)器, 同樣的,五個(gè)SIGCHLD信號(hào)到達(dá)服務(wù)器,然而,UNIX的信號(hào)往往是不會(huì)排隊(duì)的,顯然這樣一來(lái),信號(hào)處理函數(shù)將只會(huì)執(zhí)行一次,殘留剩余四個(gè)子進(jìn)程作為 僵尸進(jìn)程駐留在內(nèi)核空間。此時(shí),正確的解決辦法是利用waitpid(-1, &stat, WNOHANG)防止留下僵尸進(jìn)程。其中的pid為-1表明等待第一個(gè)終止的子進(jìn)程,而WNOHANG選擇項(xiàng)通知內(nèi)核在沒(méi)有已終止進(jìn)程項(xiàng)時(shí)不要阻塞。

            wait&waitpid 區(qū)別

            ?????? waitpid提供了wait函數(shù)不能實(shí)現(xiàn)的3個(gè)功能:

            • waitpid等待特定的子進(jìn)程, 而wait則返回任一終止?fàn)顟B(tài)的子進(jìn)程;
            • waitpid提供了一個(gè)wait的非阻塞版本;
            • waitpid支持作業(yè)控制(以WUNTRACED選項(xiàng)).
            用于檢查wait和waitpid兩個(gè)函數(shù)返回終止?fàn)顟B(tài)的宏:

            這兩個(gè)函數(shù)返回的子進(jìn)程狀態(tài)都保存在statloc指針中, 用以下3個(gè)宏可以檢查該狀態(tài):

            • WIFEXITED(status): 若為正常終止, 則為真. 此時(shí)可執(zhí)行
              • WEXITSTATUS(status): 取子進(jìn)程傳送給exit或_exit參數(shù)的低8位.
            • WIFSIGNALED(status): 若為異常終止, 則為真. 此時(shí)可執(zhí)行
              • WTERMSIG(status):?? 取使子進(jìn)程終止的信號(hào)編號(hào).
            • WIFSTOPPED(status): 若為當(dāng)前暫停子進(jìn)程, 則為真. 此時(shí)可執(zhí)行
            WSTOPSIG(status): 取使子進(jìn)程暫停的信號(hào)編號(hào)

            posted on 2007-08-01 00:24 旅途 閱讀(1273) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): Linux開(kāi)發(fā)

            国产一区二区精品久久岳| 久久亚洲国产成人影院网站| 国产香蕉久久精品综合网| 中文成人无码精品久久久不卡 | 99久久99久久精品国产| 久久精品国产影库免费看| 婷婷综合久久中文字幕| 久久久久黑人强伦姧人妻| 久久久婷婷五月亚洲97号色| 99久久夜色精品国产网站| 亚洲国产成人精品91久久久| 人妻精品久久久久中文字幕69 | 国产2021久久精品| 一97日本道伊人久久综合影院| 日韩久久久久久中文人妻| 久久精品国产精品亚洲人人 | 国产美女久久精品香蕉69| 久久久久亚洲av成人无码电影 | 狠狠干狠狠久久| 久久久久久免费视频| 色综合合久久天天综合绕视看 | 久久夜色精品国产亚洲| 精品久久国产一区二区三区香蕉| 亚洲AV无码久久精品狠狠爱浪潮| 国产免费久久久久久无码| 久久精品国产精品亚洲毛片| 亚洲中文字幕无码久久2017| 色偷偷88欧美精品久久久| 国产一区二区精品久久凹凸| 日本久久久久久中文字幕| 国产精品无码久久综合| 亚洲精品乱码久久久久久按摩| 成人综合久久精品色婷婷| 久久国产免费| 久久久精品人妻无码专区不卡| 狠狠精品干练久久久无码中文字幕| 成人国内精品久久久久影院| 久久久久久综合一区中文字幕| 久久久精品午夜免费不卡| 久久久久亚洲AV无码永不| 国产91色综合久久免费|