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

歡迎訪問 生活随笔!

生活随笔

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

linux

Linux系统【三】回收子进程

發布時間:2023/11/30 linux 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux系统【三】回收子进程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

孤兒進程

父進程先于子進程結束,則子進程成為孤兒進程,子進程的父進程成為init進程,則稱init進程領養孤兒進程。現在好像是用戶進程中的system進程。

僵尸進程

進程終止,父進程不進行回收,自己成殘留資源(PCB)存放在內核中,變成僵尸進程。

子進程死亡以后會將自己占用的內存(4G)釋放,但是會將死亡信息放在自己的PCB中,希望父進程調用得到子進程的死亡信息以后再清除PCB。需要注意的是僵尸進程是不能使用kill命令清除掉的,因為kill命令知識用來終止進程的,而僵尸進程已經終止。這就要求我們手動回收子進程。

這里的僵尸進程特別指的是父進程沒有結束而子進程已經結束,如果父進程結束就算我們不手動回收也會自動回收(實際過程是父進程結束以后沒有回收的子進程變成孤兒進程被init進程或者system進程回收)

wait函數回收子進程

一個進程在終止時會關閉所有的文件描述符,釋放在用戶空間分配的內存,但它的PCB還保留著,內核在其中保存了一些信息:如果是正常終止則保存著退出狀態,如果是異常終止則保存著導致該進程終止的信號是哪個。這個進程的父進程可以調用wait或者waitpid獲取這些信息,然后徹底清除這個進程。

shell下一個進程的退出狀態可以用特殊變量$?查看,因為shell是他的父進程,當它終止時shell調用wait或者waitpid得到它的退出狀態同時徹底清除掉這個進程。

wait函數可以回收子進程終止信息,該函數有三個功能:

  • 阻塞等待子進程退出:如果子進程沒有結束父進程不會干其他的事情
  • 回收子進程殘留的PCB資源
  • 獲取子進程結束狀態(退出原因)

一次wait函數只能清除一個子進程

pid_t wait(int *status);

返回值:如果成功返回子進程ID,如果失敗返回-1(沒有子進程的話就會報錯)

status保存結束狀態

  • 進程正常結束
WIFEXITED(status) 為非0說明是正常退出 WEXITSTATUS(status)如果上面宏為真,使用這個宏獲取進程退出狀態(exit的參數)
  • 進程異常終止(收到信號終止,例如段錯誤、總線錯誤、浮點數例外錯誤)
WIFSIGNALED(status) 為非0,說明程序異常終止 WTERMSIG(status)如果上面宏為真使用此宏 取得使得進程終止的那個信號的編號
  • 進程處于暫停狀態
WIFSTOPPED(status) 為非0,進程處于暫停狀態 WSTOPSIG(status) 如果上述宏為真,取得使得進程暫停的那個信號的編號 WIFCONTINUED(status) 為真表示進程暫停后已經繼續運行

waitpid函數

一次waitpid函數只能清除一個子進程,和wait函數類似

pid_t waitpid(pid_t pid,int* status,int options)

第一個參數用于指定需要回收的進程ID,第三個參數可以設置不阻塞回收,即僅僅返回一個狀態

pid:

  • 大于0 表示回收的子進程ID
  • -1 表示回收任意子進程(相當于wait)
  • 0 回收當前調用waitpid一個組的任意子進程,在一般情況下和-1相同
  • <-1 回收指定進程組內的任意子進程,-進程組ID,進程組ID可以用ps ajx查看
    options:
  • 當參數為WNOHANG,非阻塞回收,輪詢查看
  • 當參數為0的時候,阻塞回收,相當于wait

返回值:

  • 成功返回子進程ID
  • 失敗返回-1
  • 如果輪詢訪問回收子進程的時候子進程沒有結束則返回0
    例如:
#include<stdio.h> #include<stdlib.h> #include<sys/types.h> #include<sys/wait.h> #include<unistd.h>int main(int argc, char* argv[]) {int n=5;if(argc>2){printf("too many arguments\n");exit(1);}else if(argc==2){n = atoi(argv[1]);}int pi;pid_t p,q;for(pi=0;pi<n;++pi){p=fork();if(0 == p){break;}else if(3 == pi){q = p;}}if(n==pi){printf("I am parent,pid = %d\n",getpid());//刪除單個子進程//waitpid(q,NULL,0);//循環刪除子進程//while(-1!=waitpid(-1,NULL,0));//非阻塞刪除子進程pid_t tid;do{tid=waitpid(-1,NULL,WNOHANG);}while(tid != -1);printf("OK\n");while(1);}else{printf("I am child,pid = %d\n",getpid());}return 0; }

總結

以上是生活随笔為你收集整理的Linux系统【三】回收子进程的全部內容,希望文章能夠幫你解決所遇到的問題。

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