日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux系统编程——僵尸的模拟以及僵尸进程的预防

發布時間:2025/3/15 linux 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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系统编程——僵尸的模拟以及僵尸进程的预防的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。