有關僵尸進程和孤兒進程的解釋
僵尸進程:一個子進程在其父進程還沒有調用wait()或waitpid()的情況下退出。這個子進程就是僵尸進程。
孤兒進程:一個父進程退出,而它的一個或多個子進程還在運行,那么那些子進程將成為孤兒進程。孤兒進程將被init進程(進程號為1)所收養,并由init進程對它們完成狀態收集工作。
僵尸進程將會導致資源浪費,而孤兒則不會。
子進程持續10秒鐘的僵尸狀態(EXIT_ZOMBIE)
------------------------------------------------------
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
main()
{
pid_t pid;
pid = fork();
if(pid < 0)
printf("error occurred!"n");
else if(pid == 0) {
printf("Hi father! I'm a ZOMBIE"n");
exit(0); //(1)
}
else {
sleep(10);
wait(NULL); //(2)
}
}
(1) 向父進程發送SIGCHILD信號
(2) 父進程處理SIGCHILD信號
執行exit()時根據其父進程的狀態決定自己的狀態:
如果父進程已經退出(沒有wait),則該子進程將會成為孤兒進程過繼給init進程
如果其父進程還沒有退出,也沒有wait(),那么該進程將向父進程發送SIGCHILD信號,進入僵尸狀態等待父進程為其收尸。如果父進程一直沒有執行wait(),那么該子進程將會持續處于僵尸狀態。
子進程將成為孤兒進程
------------------------------------------------------
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
main()
{
pid_t pid;
pid = fork();
if(pid < 0)
printf("error occurred!"n");
else if(pid == 0) {
sleep(6);
printf("I'm a orphan"n");
exit(0);
}
else {
sleep(1);
printf("Children Bye!"n");
}
}
# ./a.out
Children Bye!
# I'm a orphan
(回車后將會進入#)
上面是我在網上找到的一篇簡潔又清晰的有關僵尸/孤兒進程的介紹,我再補充點自己的體會:
任何一個進程退出時,都會給自己的父進程發送一個SIGCHLD/SIGCLD,如果父進程在創建子進程之前調用了signal(SIGCHLD, SIG_IGN),那么子進程將立刻退出,也就不存在什么僵尸進程了;對于上面的第一個例子,假如在父進程中sleep之后沒有調用wait,那么由子進程發送過來的SIGCHLD信號也不會再拋給init進程(即,不會從僵尸進程轉化為孤兒進程);
父親比孩子死得早,孩子就是孤兒進程,因此孤兒進程的開始不是從子進程exit后算的,而是從父進程死亡的那一刻算的;
僵尸進程的首要必要條件就是:父親得活著;其次,子進程成為僵尸的時間長度==父進程不搭理子進程的時間長度(即, 不調用wait或waitpid)。
孤兒進程:一個父進程退出,而它的一個或多個子進程還在運行,那么那些子進程將成為孤兒進程。孤兒進程將被init進程(進程號為1)所收養,并由init進程對它們完成狀態收集工作。
僵尸進程將會導致資源浪費,而孤兒則不會。
子進程持續10秒鐘的僵尸狀態(EXIT_ZOMBIE)
------------------------------------------------------
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
main()
{
pid_t pid;
pid = fork();
if(pid < 0)
printf("error occurred!"n");
else if(pid == 0) {
printf("Hi father! I'm a ZOMBIE"n");
exit(0); //(1)
}
else {
sleep(10);
wait(NULL); //(2)
}
}
(1) 向父進程發送SIGCHILD信號
(2) 父進程處理SIGCHILD信號
執行exit()時根據其父進程的狀態決定自己的狀態:
如果父進程已經退出(沒有wait),則該子進程將會成為孤兒進程過繼給init進程
如果其父進程還沒有退出,也沒有wait(),那么該進程將向父進程發送SIGCHILD信號,進入僵尸狀態等待父進程為其收尸。如果父進程一直沒有執行wait(),那么該子進程將會持續處于僵尸狀態。
子進程將成為孤兒進程
------------------------------------------------------
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
main()
{
pid_t pid;
pid = fork();
if(pid < 0)
printf("error occurred!"n");
else if(pid == 0) {
sleep(6);
printf("I'm a orphan"n");
exit(0);
}
else {
sleep(1);
printf("Children Bye!"n");
}
}
# ./a.out
Children Bye!
# I'm a orphan
(回車后將會進入#)
上面是我在網上找到的一篇簡潔又清晰的有關僵尸/孤兒進程的介紹,我再補充點自己的體會:
任何一個進程退出時,都會給自己的父進程發送一個SIGCHLD/SIGCLD,如果父進程在創建子進程之前調用了signal(SIGCHLD, SIG_IGN),那么子進程將立刻退出,也就不存在什么僵尸進程了;對于上面的第一個例子,假如在父進程中sleep之后沒有調用wait,那么由子進程發送過來的SIGCHLD信號也不會再拋給init進程(即,不會從僵尸進程轉化為孤兒進程);
父親比孩子死得早,孩子就是孤兒進程,因此孤兒進程的開始不是從子進程exit后算的,而是從父進程死亡的那一刻算的;
僵尸進程的首要必要條件就是:父親得活著;其次,子進程成為僵尸的時間長度==父進程不搭理子進程的時間長度(即, 不調用wait或waitpid)。