• <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

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            色婷婷久久综合中文久久一本| 久久人搡人人玩人妻精品首页| 性欧美大战久久久久久久久 | 777米奇久久最新地址| 久久精品人人槡人妻人人玩AV | 国产综合精品久久亚洲| 久久人人爽人人澡人人高潮AV| 久久99久久99精品免视看动漫| 精品伊人久久大线蕉色首页| 国产精品一久久香蕉国产线看| 成人精品一区二区久久| 中文字幕无码免费久久| 国产高清美女一级a毛片久久w| 亚洲色欲久久久综合网| 久久国产综合精品五月天| 亚洲AV日韩AV天堂久久| 久久福利片| 久久国产成人精品麻豆| 色婷婷久久久SWAG精品| 99久久精品免费看国产一区二区三区 | 久久久久久国产a免费观看不卡| 少妇无套内谢久久久久| 18岁日韩内射颜射午夜久久成人| yy6080久久| 久久av高潮av无码av喷吹| 99久久精品国产免看国产一区| 久久人人爽人人爽人人爽| 久久99精品九九九久久婷婷| 99久久久精品| 2021久久精品国产99国产精品| 中文国产成人精品久久不卡 | 久久99精品久久久久久久不卡 | 2019久久久高清456| 理论片午午伦夜理片久久| 久久久WWW成人免费毛片| 91精品婷婷国产综合久久| 99久久婷婷免费国产综合精品| 无码日韩人妻精品久久蜜桃| 精产国品久久一二三产区区别 | 麻豆av久久av盛宴av| 狠狠色综合网站久久久久久久|