於程式中查看到signal(SIGCHLD,SIG_IGN),了解一下用意
更新記錄
item | note |
---|---|
20160908 | 第一版 |
目錄
彊屍程序(zombie)
僵屍 (zombie) 程序是什麼
造成僵屍程序的成因是因為該程序應該已經執行完畢,或者是因故應該要終止了, 但是該程序的父程序卻無法完整的將該程序結束掉,而造成那個程序一直存在記憶體當中
ps
ps
1
2
3
4
5
6
7
8
9
10
11
12xx :[~]# ps
PID USER VSZ STAT COMMAND
1 root 2164 S init
2 root 0 SW [kthreadd]
3 root 0 SW [ksoftirqd/0]
xx
1315 root 1604 S ./a.out
1316 root 0 Z [a.out]
1317 root 0 Z [a.out]
1318 root 0 Z [a.out]
1319 root 0 Z [a.out]
1320 root 0 Z [a.out]VSZ : 該 process 使用掉的虛擬記憶體量 (Kbytes)
- STAT : 該程序目前的狀態,狀態顯示與 ps -l 的 S 旗標相同 (R/S/T/Z)
- R (Running)
- S (Sleep):該程式目前正在睡眠狀態(idle),但可以被喚醒(signal)
- T :停止狀態(stop),可能是在工作控制(背景暫停)或除錯 (traced) 狀態
- Z (Zombie):僵屍狀態,程序已經終止但卻無法被移除至記憶體外
example (未加入SIGCHLD訊息處理)
未加入SIGCHLD訊息處理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <stdio.h>
#include <unistd.h>
int main(){
int i;
pid_t pid;
for( i=0; i<5; i++) {
pid = fork();
if ( pid == 0 )
break;
}
if( pid > 0 ){
printf("press enter to exit ..");
getchar();
}
return 0;
}結果如下
當子程序結束,父程序仍在
而父程序fork()之前未設置SIGCHILD信號處理或waitpid等待子程序結束
此時會產生 僵屍程序(zombie), 若父程序一直存在不會結束,就會看到一堆zombie1
2
3
4
5
61315 root 1604 S ./a.out
1316 root 0 Z [a.out]
1317 root 0 Z [a.out]
1318 root 0 Z [a.out]
1319 root 0 Z [a.out]
1320 root 0 Z [a.out]
example (加入SIGCHLD訊息處理)
加入SIGCHLD訊息處理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <stdio.h>
#include <unistd.h>
#include <sys/signal.h>
int main(){
int i;
pid_t pid;
signal(SIGCHLD, SIG_IGN);
for( i=0; i<5; i++) {
pid = fork();
if ( pid == 0 )
break;
}
if( pid > 0 ){
printf("press enter to exit ..");
getchar();
}
return 0;
}測試
1
21454 root 1604 S ./a.out
1460 root 2168 R ps
fork
- The purpose of fork() is to create a new process, which becomes the child process of the caller
- If fork() returns a negative value, the creation of a child process was unsuccessful.
- fork() returns a zero to the newly created child process.
- fork() returns a positive value, the process ID of the child process, to the parent.
- The fork() System Call
fork example
ex1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <stdio.h>
#include <string.h>
#include <sys/types.h>
void main(void)
{
pid_t pid;
int i;
char buf[100];
fork();
pid = getpid();
for(i =1; i <= 200; i++){
sprintf(buf, "This line is from pid %d, value = %d \n", pid, i);
write(1,buf,strlen(buf));
}
}測試
1
2
3
4
5
6
7
8
9
10
11
12
13xx :[~]# ./a.out
This line is from pid 1498, value = 1
This line is from pid 1498, value = 2
This line is from pid 1498, value = 3
This line is from pid 1498, value = 4
This line is from pid 1498, value = 5
This line is from pid 1498, value = 6
This line is from pid 1498, value = 7
This line is from pid 1498, value = 8
This line is from pid 1498, value = 9
This line is from pid 1499, value = 1
This line is from pid 1498, value = 10
This line is from pid 1499, value = 2
fork之後會產生1個子程序,跟父程序同時進行,因此會看到有兩個pid,獨立算數
fork出來的子程序是由原本的父程序複製全部的變數(kernel需要的系統參數),因此是跟父程序獨立分開的process
fork ex2
fork ex2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
void ChildProcess(){
pid_t pid;
pid = getpid();
printf("child pid:%d\n",pid);
getchar();
}
void ParentProcess(){
pid_t pid;
pid = getpid();
printf("parent pid:%d\n",pid);
getchar();
}
void main(void)
{
pid_t pid;
int i;
char buf[100];
pid = fork();
if ( pid == 0 )
ChildProcess();
else
ParentProcess();
}測試
1
21559 root 1604 S ./a.out
1560 root 1604 S ./a.outfork回傳0則為child process