• <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 閱讀(555) 評論(0)  編輯 收藏 引用 所屬分類: Linux_Coding
            <2010年8月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234

            常用鏈接

            留言簿(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

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            97超级碰碰碰碰久久久久| 午夜精品久久久久久久无码| 色偷偷88888欧美精品久久久| 无码久久精品国产亚洲Av影片| 久久国产精品久久久| 久久精品视频91| 97久久久精品综合88久久| 久久综合九色综合欧美就去吻| 久久综合久久自在自线精品自 | 成人a毛片久久免费播放| 亚洲欧美久久久久9999| 日本久久久精品中文字幕| 久久婷婷五月综合97色直播| 国产成人精品久久亚洲高清不卡| 99久久精品国产一区二区| 欧美性猛交xxxx免费看久久久 | 精品久久久久久无码免费| 久久婷婷五月综合色奶水99啪| 久久精品国产精品青草app| 国产香蕉久久精品综合网| 办公室久久精品| 91精品国产91久久久久久| 久久夜色精品国产网站| 中文字幕无码免费久久| 开心久久婷婷综合中文字幕| 亚洲嫩草影院久久精品| 久久99精品久久久久久久久久| 久久久久久精品免费看SSS| 国产精品久久新婚兰兰| 四虎久久影院| 久久婷婷五月综合国产尤物app| 亚洲欧洲久久久精品| 亚洲欧美日韩精品久久亚洲区| 久久91这里精品国产2020| 国产精品热久久毛片| 精品国产91久久久久久久a| 国产精品狼人久久久久影院| 日本久久久久久中文字幕| 久久男人AV资源网站| 久久人人超碰精品CAOPOREN| 久久精品中文字幕第23页|