星期三, 3月 08, 2017
[ C ] Fork() 和 Zombie
Fork()是複製一份和自己一模一樣的process出來,
回傳的值是pid,
所以可以用判斷pid的方式,把程式分成parent和child部份,
注意的是,
他是從fork()之後的程式碼開始執行起,
如果在那之前會執行不到。
=====Output=====
#####Now pid [8654]
I am the parent process, Count is 0 , ID is 8654 , Parent ID is 32489 , fork id is 8655
Process End
I am the child process, Count is 0 , ID is 8655 , Parent ID is 8654 , fork id is 0
Process End
SourceCode
"The process that has terminated, but whose parent hasn’t yet waited for it."
1. 如果parent先死掉,那child還在執行時,不會變成zombie,因為會由init(pid 1)來接收,並且wait()他結束。
2. zombie是指child結束了,要等待parent來處理child結束後的事,但這時一直都沒人處理。
zombie process的形成是因為parent還沒結束,
在產生child後,child執行完後時,
而parent process卻還沒執行完畢,
在這時child process執行完了就會變成zombie。
====================================================
vodka 8990 0.0 0.0 4088 664 pts/7 S 20:10 0:00 ./a.out
vodka 8992 0.0 0.0 0 0 pts/7 Z 20:10 0:00 [a.out] <defunct>
vodka 8996 0.0 0.0 9380 2204 pts/7 S+ 20:10 0:00 grep a.out
====================================================
他會佔著一些空間不放,像是process id / termination status ...
佔據太多pid,process達到了上限,就無法再執行程式。
處理方法有以下幾種:
1. 在parent裡就宣告說我不需要知道child process的結束狀態。
signal(SIGCHLD, SIG_IGN);
2. 兩次的fork讓init 來接收child。
因為linux會在一個process結束時,自動把該process的parent變成init,
然後該process就由init所接管。
所以利用這樣的概念,
Step 1:
Process A => fork() -> parent繼續做他的事,child (B) 再去fork另一個process。
Step 2:
Process B => fork -> parent跳離(不執行其他動作),child去做自己的事。
Step 3:
如此一來在Process B時,因為parent結束了,所以child歸init管。
3. 利用wait來等待
3-1 用wait來等全部child
int i = wait(NULL);
printf("waiting for pid [%d]\n",i);
3-2 用waitpid來等特定pid
waitpid(pid, NULL, WNOHANG);
WaitSourceCode
TwiceForkSourceCode
Ref
Ref_2
Ref_3
Ref_4
訂閱:
張貼留言 (Atom)

沒有留言:
張貼留言