Linux系统编程——僵尸的模拟以及僵尸进程的预防
生活随笔
收集整理的這篇文章主要介紹了
Linux系统编程——僵尸的模拟以及僵尸进程的预防
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
僵尸進程介紹
子進程終止,父進程尚未回收,子進程殘留資源(PCB)存放于內核中,變成僵尸進程。由于我們的程序也許是7*24小時不宕機的,程序不結束,僵尸進程殘留在PCB中資源就不會被回收,所以我們要清晰的認識僵尸進程,在程序中盡量避免僵尸進程。
僵尸進程模擬
我們通過下面程序來進行模擬僵尸進程,父進程fork()5個子進程,最后一個子進程用于查看僵尸進程,讓父進程最后死亡。
代碼展示
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <error.h> #include <sys/errno.h>void perr(const char* str) {perror(str);exit(1); } int main(int argc,char* argv[]) {pid_t pid;int i;for( i = 0; i < 5;i++ ){if( (pid = fork()) == 0 ){break; //子進程}else if (pid < 0){perr("fork error"); }}if( i < 4 ) //子進程0,1,2,3 最先死亡 模擬僵尸進程{printf("i am child process,pid = %d,ppid = %d.i am died.\n",getpid(),getppid());exit(1);}else if( i==4 ) //子進程4 顯示僵尸進程{sleep(1);printf("i am child process[exec ps],pid = %d,ppid = %d.\n",getpid(),getppid());execlp("ps","ps","j",NULL);}else //父進程活3秒 查看僵尸進程現象 {printf("i am parent process,pid = %d,ppid = %d.i will die after 3s.\n",getpid(),getppid());sleep(3);}return 0; }僵尸進程現象
僵尸進程預防
如何預防僵尸進程呢?可能很多人都知道,子進程死亡了父進程回收資源唄。對,只要子進程死亡了,父進程負責收尸就行了。
這里有2種方式回收子進程資源。如下:
- 父進程在死亡之前輪詢的去查看子進程是否死亡,死亡了就回收,主要使用wait/waitpid
- 父進程由自己的事情做,子進程死亡了通知父進程收尸,主要使用信號回調signal/sigaction
這里最好的方式當然是采用信號唄,有子進程死亡,父進程才進行回收!
代碼展示
代碼中要注意的是,子進程可能同時終止,同時發送信號,父進程執行信號回調函數但是默認只處理1個,所以要用while進行回收! while( (wpid = waitpid(-1,NULL,WNOHANG)) != -1 );
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <error.h> #include <sys/errno.h> #include <signal.h> #include <wait.h>void perr(const char* str) {perror(str);exit(1); } void wait_child(int signo) {pid_t wpid;//子進程可能同時終止,同時發送信號到這里來默認只處理1個,所以要用while!while( (wpid = waitpid(-1,NULL,WNOHANG)) != -1 );waitpid(-1,NULL,0); } int main(int argc,char* argv[]) {pid_t pid;int i;struct sigaction act;act.sa_flags = 0;act.sa_handler = wait_child; sigemptyset(&act.sa_mask);sigaction(SIGCHLD,&act,NULL);for( i = 0; i < 5;i++ ){if( (pid = fork()) == 0 ){break; //子進程}else if (pid < 0){perr("fork error"); }}if( i < 4 ) //子進程0,1,2,3 最先死亡 模擬僵尸進程{printf("i am child process,pid = %d,ppid = %d.i am died.\n",getpid(),getppid());exit(1);}else if( i==4 ) //子進程4 顯示僵尸進程{sleep(1); printf("i am child process[exec ps],pid = %d,ppid = %d.\n",getpid(),getppid());execlp("ps","ps","j",NULL);}else //父進程活3秒 查看僵尸進程現象{printf("i am parent process,pid = %d,ppid = %d.i will die after 3s.\n",getpid(),getppid());sleep(3);}return 0; }查看預防效果
總結
以上是生活随笔為你收集整理的Linux系统编程——僵尸的模拟以及僵尸进程的预防的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python (高级消息队列)普通、进程
- 下一篇: 树:二叉树的层序遍历算法(超简洁实现及详