• <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 閱讀(553) 評論(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

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            久久午夜电影网| 午夜精品久久久久久久| 久久免费精品视频| 99久久亚洲综合精品网站| 精品国产综合区久久久久久| 亚洲精品综合久久| 国内精品伊人久久久久av一坑| 国产精品免费久久久久电影网| 免费久久人人爽人人爽av| 久久久久人妻精品一区二区三区| 国产高潮久久免费观看| 99精品久久久久久久婷婷| 国产高潮久久免费观看| 亚洲国产精品18久久久久久| 精品久久久久久无码中文字幕| 偷偷做久久久久网站| 国产精品成人99久久久久 | 亚洲午夜久久久久久久久电影网| 久久久久久人妻无码| 欧美久久久久久精选9999| 国产高潮国产高潮久久久| 久久99国产精品久久99小说| 国产成人香蕉久久久久 | 国产精品伦理久久久久久| 99精品久久精品一区二区| 美女久久久久久| 久久久精品国产亚洲成人满18免费网站 | 亚洲成色999久久网站| 久久午夜无码鲁丝片| 国产69精品久久久久观看软件| 久久涩综合| 久久久久亚洲AV成人网人人软件| 国产成人久久精品区一区二区| 久久无码人妻一区二区三区| 嫩草伊人久久精品少妇AV| 久久午夜免费视频| 亚洲国产综合久久天堂| 天天综合久久一二三区| 亚洲国产小视频精品久久久三级| 久久精品三级视频| 欧美国产成人久久精品|