01 / 進(jìn)程退出
exit.c
/*
#include <stdlib.h>
void exit(int status);
#include <unistd.h>
void _exit(int status);
status參數(shù):是進(jìn)程退出時(shí)的一個(gè)狀態(tài)信息。父進(jìn)程回收子進(jìn)程資源的時(shí)候可以獲取到。
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
printf("hello\n");
printf("world");
// exit(0);
_exit(0);
return 0;
}
02 / 孤兒進(jìn)程
? 父進(jìn)程運(yùn)行結(jié)束,但子進(jìn)程還在運(yùn)行(未運(yùn)行結(jié)束),這樣的子進(jìn)程就稱為孤兒進(jìn)程 (Orphan Process)。
? 每當(dāng)出現(xiàn)一個(gè)孤兒進(jìn)程的時(shí)候,內(nèi)核就把孤兒進(jìn)程的父進(jìn)程設(shè)置為 init ,而 init 進(jìn)程會(huì)循環(huán)地 wait() 它的已經(jīng)退出的子進(jìn)程。這樣,當(dāng)一個(gè)孤兒進(jìn)程凄涼地結(jié)束 了其生命周期的時(shí)候,init 進(jìn)程就會(huì)代表黨和政府出面處理它的一切善后工作。
? 因此孤兒進(jìn)程并不會(huì)有什么危害。
orphan.c
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main() {
// 創(chuàng)建子進(jìn)程
pid_t pid = fork();
// 判斷是父進(jìn)程還是子進(jìn)程
if(pid > 0) {
printf("i am parent process, pid : %d, ppid : %d\n", getpid(), getppid());
} else if(pid == 0) {
sleep(1);
// 當(dāng)前是子進(jìn)程
printf("i am child process, pid : %d, ppid : %d\n", getpid(),getppid());
}
// for循環(huán)
for(int i = 0; i < 3; i++) {
printf("i : %d , pid : %d\n", i , getpid());
}
return 0;
}
03 / 僵尸進(jìn)程
? 每個(gè)進(jìn)程結(jié)束之后, 都會(huì)釋放自己地址空間中的用戶區(qū)數(shù)據(jù),內(nèi)核區(qū)的 PCB 沒(méi)有辦法 自己釋放掉,需要父進(jìn)程去釋放。
? 進(jìn)程終止時(shí),父進(jìn)程尚未回收,子進(jìn)程殘留資源(PCB)存放于內(nèi)核中,變成僵尸 (Zombie)進(jìn)程。
? 僵尸進(jìn)程不能被 kill -9 殺死,這樣就會(huì)導(dǎo)致一個(gè)問(wèn)題,如果父進(jìn)程不調(diào)用 wait() 或 waitpid() 的話,那么保留的那段信息就不會(huì)釋放,其進(jìn)程號(hào)就會(huì)一直被占用, 但是系統(tǒng)所能使用的進(jìn)程號(hào)是有限的,如果大量的產(chǎn)生僵尸進(jìn)程,將因?yàn)闆](méi)有可用的進(jìn) 程號(hào)而導(dǎo)致系統(tǒng)不能產(chǎn)生新的進(jìn)程,此即為僵尸進(jìn)程的危害,應(yīng)當(dāng)避免。
zombie.c
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main() {
// 創(chuàng)建子進(jìn)程
pid_t pid = fork();
// 判斷是父進(jìn)程還是子進(jìn)程
if(pid > 0) {
while(1) {
printf("i am parent process, pid : %d, ppid : %d\n", getpid(), getppid());
sleep(1);
}
} else if(pid == 0) {
// 當(dāng)前是子進(jìn)程
printf("i am child process, pid : %d, ppid : %d\n", getpid(),getppid());
}
// for循環(huán)
for(int i = 0; i < 3; i++) {
printf("i : %d , pid : %d\n", i , getpid());
}
return 0;
}
開啟?另一個(gè)終端,ps aux查看如下信息,Z+表示是僵尸進(jìn)程?
kill -9 14860 ,變成僵尸進(jìn)程(Z+),不能被kill -9殺死
?04 / 進(jìn)程回收
? 在每個(gè)進(jìn)程退出的時(shí)候,內(nèi)核釋放該進(jìn)程所有的資源、包括打開的文件、占用的內(nèi) 存等。但是仍然為其保留一定的信息,這些信息主要主要指進(jìn)程控制塊PCB的信息 (包括進(jìn)程號(hào)、退出狀態(tài)、運(yùn)行時(shí)間等)。
? 父進(jìn)程可以通過(guò)調(diào)用wait或waitpid得到它的退出狀態(tài)同時(shí)徹底清除掉這個(gè)進(jìn)程。
? wait() 和 waitpid() 函數(shù)的功能一樣,區(qū)別在于,wait() 函數(shù)會(huì)阻塞, waitpid() 可以設(shè)置不阻塞,waitpid() 還可以指定等待哪個(gè)子進(jìn)程結(jié)束。
? 注意:一次wait或waitpid調(diào)用只能清理一個(gè)子進(jìn)程,清理多個(gè)子進(jìn)程應(yīng)使用循環(huán)。
05 / 退出信息相關(guān)宏函數(shù)
? WIFEXITED(status) 非0,進(jìn)程正常退出
? WEXITSTATUS(status) 如果上宏為真,獲取進(jìn)程退出的狀態(tài)(exit的參數(shù))
? WIFSIGNALED(status) 非0,進(jìn)程異常終止
? WTERMSIG(status) 如果上宏為真,獲取使進(jìn)程終止的信號(hào)編號(hào)
? WIFSTOPPED(status) 非0,進(jìn)程處于暫停狀態(tài)
? WSTOPSIG(status) 如果上宏為真,獲取使進(jìn)程暫停的信號(hào)的編號(hào) 文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-574993.html
? WIFCONTINUED(status) 非0,進(jìn)程暫停后已經(jīng)繼續(xù)運(yùn)行文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-574993.html
到了這里,關(guān)于基于linux下的高并發(fā)服務(wù)器開發(fā)(第二章)- 2.7 進(jìn)程退出、孤兒進(jìn)程、僵尸進(jìn)程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!