UNIXC002 程式資源的回收、孤兒程式和殭屍程式
程式的資源回收
- 程式終止以後,如果父程式不來回收子程式的資源,相當於子程式的使用者態已經結束了,但是核心態沒有,子程式的PCB還在佔用著資源。這個PCD有時被稱為程式的殭屍(白白佔用系統的記憶體)。所以在子程式結束以後要及時的回收子程式的殭屍。
1. wait
1.1 可以使用以下 巨集檢測程式終止的原因
$ man 2 wait
....
WIFEXITED(status)
returns true if the child terminated normally, that is, by calling exit(3) or _exit(2), or by returning from main().
WEXITSTATUS(status)
returns the exit status of the child. This consists of the least significant 8 bits of the status argument that the child specified
in a call to exit(3) or _exit(2) or as the argument for a return statement in main(). This macro should be employed only if WIFEX‐
ITED returned true.
WIFSIGNALED(status)
returns true if the child process was terminated by a signal.
WTERMSIG(status)
returns the number of the signal that caused the child process to terminate. This macro should be employed only if WIFSIGNALED
returned true.
....
1.2 程式碼示例
wait.c
#include <stdlib.h>
#include "t_stdio.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void){
int s;
//建立子程式
pid_t pid = fork();
if(pid==-1)E_MSG("fork", -1);
if(pid == 0){
//子程式執行程式碼
printf("child process ... %d\n", getpid());
getchar();
// 終止子程式
exit(-1);
} else {
// 父程式執行程式碼
// wait 阻塞等待子程式結束, 回收子程式資源, 所以子程式執行完以後才會執行下面的printf的程式碼, 這樣就從之前的非同步,變成了現在的同步
// s用來儲存子程式的退出狀態碼
wait(&s);
if(WIFEXITED(s)){ // WIFEXITED(s) 為真說明子程式正常退出,WEXITSTATUS(s)可以獲取子程式退出狀態碼
printf("exit: %d\n", WEXITSTATUS(s));
}
if(WIFSIGNALED(s)){ // WIFSIGNALED(s) 為真說明程式是被訊號打斷的, WTERMSIG(s) 可以獲取打斷程式訊號的編號
printf("signum: %d\n", WTERMSIG(s));
}
printf("father process ...\n");
}
return 0;
}
- 子程式正常退出
- 子程式被訊號打斷
↓
2. waitpid
- wait 是等待任意子程式,只要是子程式終止那麼就把它給回收
- waitpid 可以指定某一個子程式的pid,也可以指定某一個程式組的pid
2.1 pid 引數取值說明
- pid == -1, option==0 時waitpid 完全等同於 wait
- 程式組包含多個程式,每個程式組裡都有leader程式,leader程式的pid就是這個程式組的pid
- 一般情況下父程式呼叫fork建立子程式以後,不呼叫setpgid,那麼子程式和父程式都是同組的,如果呼叫了setpgid, 那麼子程式將會被設定為另一個程式組的程式。
waitpid.c
#include <stdlib.h>
#include "t_stdio.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void){
int s;
//建立子程式
pid_t pid = fork();
if(pid==-1)E_MSG("fork", -1);
if(pid == 0){
//子程式執行程式碼
printf("child process ... %d\n", getpid());
getchar();
// 終止子程式
exit(-1);
} else {
// 父程式執行程式碼
// waitpid(-1, &s, 0); 這是非阻塞模式收子程式的資源. 阻塞: 如果要回收的子程式還沒有結束, 等著結束回收資源以後再去執行下面的
// waitpid(-1, &s, WNOHANG); 這是非阻塞模式收子程式的資源。非阻塞: 如果要回收的子程式還沒有結束,waitpid直接返回0, 不等子程式了
int w=waitpid(-1, &s, WNOHANG);
if(w==0){// 沒有子程式的資源回收,直接結束
printf("parent exit ...\n");
return 0;
}
// 返回值不是0,說明有子程式資源的回收, 再根據返回的狀態碼來判斷子程式是怎麼終止的
if(WIFEXITED(s)){ // WIFEXITED(s) 為真說明子程式正常退出,WEXITSTATUS(s)可以獲取子程式退出狀態碼
printf("exit: %d\n", WEXITSTATUS(s));
}
if(WIFSIGNALED(s)){ // WIFSIGNALED(s) 為真說明程式是被訊號打斷的, WTERMSIG(s) 可以獲取打斷程式訊號的編號
printf("signum: %d\n", WTERMSIG(s));
}
printf("father process ...\n");
}
return 0;
}
# 父程式沒有等子程式直接終止
$ ./a.out
parent exit ...
child process ... 30610
孤兒程式和殭屍程式
- 上圖的init 改為 upstart
1. 孤兒程式程式碼示例
#include "t_stdio.h"
#include <unistd.h>
#include <sys/types.h>
int main(void){
pid_t pid = fork();
if(pid == -1)E_MSG("fork", -1);
if(pid == 0){
// 在子程式中執行的程式碼
printf("父程式還沒終止時的pid: %d", getppid());
printf("子程式的pid: %d\n", getpid());
sleep(2);
printf("父程式終止以後,但是子程式沒有終止情況下,父程式的pid: %d", getppid());
} else {
// 在父程式中執行的程式碼
sleep(1);
printf("parent process ...\n");
}
return 0;
}
$ ./a.out
父程式還沒終止時的pid: 27663子程式的pid: 27664
parent process ...
$ 父程式終止以後,但是子程式沒有終止情況下,父程式的pid: 2524
$ ps -aux| grep 2524
moonx 2524 0.0 0.0 48216 2512 ? Ss 11月23 0:19 /sbin/upstart --user
moonx 28021 0.0 0.0 15968 1080 pts/21 S+ 19:23 0:00 grep --color=auto 2524
2. 殭屍程式程式碼示例
#include <stdlib.h>
#include "t_stdio.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void){
int s;
//建立子程式
pid_t pid = fork();
if(pid==-1)E_MSG("fork", -1);
if(pid == 0){
//子程式執行程式碼
exit(-1);
} else {
// 父程式執行程式碼
getchar();
wait(NULL);
}
return 0;
}
$ ./a.out
## 再開啟一個shell,子程式 [a.out] <defunct> 處於殭屍狀態 Z+
$ ps -aux| grep a.out
moonx 32381 0.0 0.0 4356 600 pts/21 S+ 19:30 0:00 ./a.out
moonx 32382 0.0 0.0 0 0 pts/21 Z+ 19:30 0:00 [a.out] <defunct>
moonx 32410 0.0 0.0 15964 980 pts/31 S+ 19:30 0:00 grep --color=auto a.out
相關文章
- 殭屍程式和孤兒程式
- 殭屍程式,孤兒程式
- Perl程式:殭屍程式和孤兒程式
- 子程式、孤兒程式,殭屍程式, init程式
- Go Exec 殭屍與孤兒程式Go
- PHP 多程式之孤兒和殭屍簡單講解PHP
- 孤兒程序和殭屍程序
- 從一道面試題來學習前臺程式和後臺程式、孤兒程式和殭屍程式面試題
- 殭屍程式,孤兒程式,wait,exit,execl等函式使用要點AI函式
- linux系統程式設計之程式(三):程式複製fork,孤兒程式,殭屍程式Linux程式設計
- SCP使用SIGSTOP後臺執行並簡單討論孤兒程式殭屍程式
- fork和殭屍程式
- 殭屍程式
- 聊聊 PHP 多程序模式下的孤兒程序和殭屍程序PHP模式
- 什麼是殭屍程式,如何找到並殺掉殭屍程式?
- Linux 殭屍程式Linux
- 【系統】 殭屍程式
- 殺死殭屍程式
- Linux中殭屍程式是什麼意思?怎麼檢視殭屍程式?Linux
- 程序物件、殭屍程序與孤兒程序、守護程序、互斥鎖物件
- 檢視 Linux 殭屍程式Linux
- Linux殭屍程式處置Linux
- 關於LINUX殭屍程式的出現和原理Linux
- Linux 中殭屍程式詳解Linux
- Linux 系統中殭屍程式Linux
- Linux如何殺掉殭屍程式Linux
- 檢視並殺死殭屍程式
- Linux程式管理、程式建立、執行緒實現、殭屍程式Linux執行緒
- 孤兒程式與終端的關係
- Linux系統程式設計——特殊程式之孤兒程式Linux程式設計
- Linux系統殭屍程式詳解Linux
- 什麼是殭屍程式以及如何處理
- JaCoCo助您毀滅線上殭屍程式碼
- 系統中出現大量不可中斷程式(D)和殭屍程式(Z)怎麼辦?
- 物聯網教程Linux系統程式設計——特殊程式之殭屍程式Linux程式設計
- mysql連線池爆滿,釋放程式長連線殭屍程式MySql
- Linux 效能優化之 CPU 篇 ----- 殭屍程式Linux優化
- 案例:系統中出現大量不可中斷程式(D)和殭屍程式(Z)怎麼辦?