• <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>
            posts - 297,  comments - 15,  trackbacks - 0
            一個進程在調用exit命令結束自己的生命的時候,其實它并沒有真正的被銷毀,而是留下一個稱為僵尸進程(Zombie)的數據結構(系統調用exit,它的作用是使進程退出,但也僅僅限于將一個正常的進程變成一個僵尸進程,并不能將其完全銷毀)。在Linux進程的狀態中,僵尸進程是非常特殊的一種,它已經放棄了幾乎所有內存空間,沒有任何可執行代碼,也不能被調度,僅僅在進程列表中保留一個位置,記載該進程的退出狀態等信息供其他進程收集,除此之外,僵尸進程不再占有任何內存空間。它需要它的父進程來為它收尸,如果他的父進程沒安裝SIGCHLD信號處理函數調用wait或waitpid()等待子進程結束,又沒有顯式忽略該信號,那么它就一直保持僵尸狀態,如果這時父進程結束了,那么init進程自動
            會接手這個子進程,為它收尸,它還是能被清除的。但是如果如果父進程是一個循環,不會結束,那么子進程就會一直保持僵尸狀態,這就是為什么系統中有時會有很多的僵尸進程。
            怎么查看僵尸進程:
            利用命令ps,可以看到有標記為Z的進程就是僵尸進程。
             
               先看段代碼

            #include <sys/types.h>
            #include <sys/wait.h>
            #include <unistd.h>
            #include <stdlib.h>
            #include <stdio.h>

            int main(int argc, char** argv)
            {
              int num = 6;
              pid_t pid;
             
              if((pid=fork())<0)
                {
                 printf("fork error\n");
                 return -1;
                }
              else if(pid==0)
               {
                    num += 2;
                 printf("this is child %d,parent %d, num is %d\n", getpid(), getppid(), num);
                 exit(0);
               }
             

             sleep(1);
              printf("this is %d,parent %d, num is %d\n", getpid(), getppid(), num);
             system("ps -o pid,ppid,state,tty,command");
             return 0;
            }

            輸出

            this is child 3647,parent 3646, num is 8
              PID  PPID S TT       COMMAND
             3077  3028 S pts/2    bash
             3646  3077 S pts/2    ./zombie
             3647  3646 Z pts/2    [zombie] <defunct>
             3649  3646 R pts/2    ps -o pid,ppid,state,tty,command
            this is 3646,parent 3077, num is 6

            看到了,這就是個zombie

             

            怎樣來避免僵尸進程:
            1.改寫父進程,在子進程死后要為它收尸。具體做法是接管SIGCHLD信號。子進程死后,會發送SIGCHLD信號給父進程,父進程收到此信號后,執行waitpid()函數為子進程收尸。這是基于這樣的原理:就算父進程沒有調用wait,內核也會向它發送SIGCHLD消息,盡管對的默認處理是忽略,如果想響應這個消息,可以設置一個處理函數。
            2.把父進程殺掉。父進程死后,僵尸進程成為"孤兒進程",過繼給1號進程init,init始終會負責清理僵尸進程.它產生的所有僵尸進程也跟著消失。


             

            #include <sys/types.h>
            #include <sys/wait.h>
            #include <unistd.h>
            #include <stdlib.h>
            #include <stdio.h>

            int main(int argc, char** argv)
            {
              int num = 6;
              pid_t pid;
             
              if((pid=fork())<0)
                {
                 printf("fork error\n");
                 return -1;
                }
              else if(pid==0)
               {
                #if 1
                if((pid=fork())<0)
                 {
                 printf("fork error\n");
                 return -1;
                 }
                else if(pid>0)
                 exit(0);
                 
                 sleep(1);
                #endif
                 num += 2;
                 printf("this is child %d,parent %d, num is %d\n", getpid(), getppid(), num);
                 exit(0);
               }
              #if 1
              if(waitpid(pid, NULL, 0)!=pid)
                {
                  printf("waitpid error\n");
                  return -1;
                }
              #endif
              sleep(1);
              printf("this is %d,parent %d, num is %d\n", getpid(), getppid(), num);
              
            //while(1)

                
            //;

              
             system("ps -o pid,ppid,state,tty,command");
             return 0;
            }

            輸出

            this is child 3629,parent 1, num is 8
              PID  PPID S TT       COMMAND
             3077  3028 S pts/2    bash
             3627  3077 S pts/2    ./zombie
             3630  3627 R pts/2    ps -o pid,ppid,state,tty,command
            this is 3627,parent 3077, num is 6

             

            waitpid為第一個子進程收死,避免第一個子進程為zombie,而孫進程則由交給init了,

            this is child 3629,parent 1, num is 8
            于是就沒有state為Z的zombie了!!!!!


            《轉自》http://blog.chinaunix.net/u2/76292/showart.php?id=2064840

            posted on 2009-10-06 23:42 chatler 閱讀(552) 評論(0)  編輯 收藏 引用 所屬分類: Linux_Coding
            <2010年6月>
            303112345
            6789101112
            13141516171819
            20212223242526
            27282930123
            45678910

            常用鏈接

            留言簿(10)

            隨筆分類(307)

            隨筆檔案(297)

            algorithm

            Books_Free_Online

            C++

            database

            Linux

            Linux shell

            linux socket

            misce

            • cloudward
            • 感覺這個博客還是不錯,雖然做的東西和我不大相關,覺得看看還是有好處的

            network

            OSS

            • Google Android
            • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
            • os161 file list

            overall

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            伊人久久大香线蕉综合热线| 久久久久久九九99精品| 99精品久久精品| 奇米影视7777久久精品| 国产精品乱码久久久久久软件| 国产精品久久久久一区二区三区| 91精品国产高清久久久久久io| 久久亚洲私人国产精品| 人妻无码αv中文字幕久久琪琪布 人妻无码久久一区二区三区免费 人妻无码中文久久久久专区 | 亚洲国产精品久久电影欧美| 久久亚洲av无码精品浪潮| 久久久久国产亚洲AV麻豆| 精品久久人人做人人爽综合| 国产免费福利体检区久久| 91精品国产91久久久久久青草| a高清免费毛片久久| 国内精品免费久久影院| 亚洲国产精品综合久久网络| 2021国产精品午夜久久| 久久婷婷色综合一区二区| 亚洲AV无码久久寂寞少妇| 久久九九精品99国产精品| 欧美亚洲另类久久综合| 久久亚洲欧洲国产综合| 综合网日日天干夜夜久久| 久久精品中文闷骚内射| 国产午夜精品久久久久九九| 人妻系列无码专区久久五月天| 久久久久久精品免费免费自慰 | 亚洲国产成人久久综合一区77| 香蕉久久影院| 蜜臀av性久久久久蜜臀aⅴ麻豆 | 狠狠色丁香婷婷综合久久来 | 欧美黑人激情性久久| 777久久精品一区二区三区无码| 久久久久无码国产精品不卡| 久久天天躁狠狠躁夜夜2020一| 无码人妻少妇久久中文字幕蜜桃| 精品乱码久久久久久夜夜嗨| 日本强好片久久久久久AAA| 久久免费观看视频|