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

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            国产精品久久久久影院色 | 欧美无乱码久久久免费午夜一区二区三区中文字幕 | 亚洲国产精品综合久久一线| 久久久久亚洲精品男人的天堂| 亚洲午夜精品久久久久久浪潮 | 亚洲午夜精品久久久久久人妖| 精品无码久久久久久国产| 2019久久久高清456| 99久久99这里只有免费费精品| 日韩一区二区久久久久久| 热久久视久久精品18| 日本一区精品久久久久影院| 久久无码高潮喷水| 久久精品国产精品亚洲人人| 久久亚洲中文字幕精品有坂深雪| 久久精品综合一区二区三区| 久久99精品国产麻豆| 久久久久高潮综合影院| 久久精品18| 狠狠色丁香久久综合五月| 久久精品国产亚洲AV忘忧草18 | 国产精品美女久久久久AV福利| 亚洲国产精品无码久久久蜜芽 | 久久久久久久99精品免费观看| | 精品999久久久久久中文字幕| 久久久久久久波多野结衣高潮| 岛国搬运www久久| 99国产欧美精品久久久蜜芽 | 久久精品免费网站网| 久久精品国产99国产精品澳门| 亚洲国产一成人久久精品| 2021最新久久久视精品爱| 亚洲欧美一区二区三区久久| 日产久久强奸免费的看| 久久国产视频网| 亚洲精品综合久久| 日韩欧美亚洲综合久久| 久久久久亚洲国产| 午夜人妻久久久久久久久| 久久久无码人妻精品无码|