1.什么是僵尸进程
一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他,那么他将变成一个僵尸进程。当用ps命令观察进程的执行状态时,看到这些进程的状态栏为defunct。如果该进程的父进程先结束,那么该进程就不会变成僵尸进程。因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程,看看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init进程来接管他,成为他的父进程,从而保证每个进程都会有一个父进程。而Init进程会自动wait其子进程,因此被Init接管的所有进程都不会变成僵尸进程。
僵尸进程实例:
代码如下:
1 #include2 #include 3 #include 4 #include 5 #include 6 7 int main() 8 { 9 char* s = NULL; 10 int n = 0; 11 12 pid_t pid = fork(); 13 assert(pid != -1); 14 15 if(pid == 0) 16 { 17 s = "child"; 18 n = 3; 19 } 20 else 21 { 22 s = "parent"; 23 n = 7; 24 } 25 26 for(int i = 0;i < n;i++ ) 27 { 28 printf("pid = %d,s = %sn",getpid(),s); 29 sleep(1); 30 31 } 32 exit(3);//退出程序,并返回值3 33 } 34
编译代码,使可执行程序在后台运行,在运行过程中用ps命令查看进程
wys@DESKTOP-2OU3HRV:~/mycode/day09$ gcc -o main main.c wys@DESKTOP-2OU3HRV:~/mycode/day09$ ls main main.c wys@DESKTOP-2OU3HRV:~/mycode/day09$ ./main& [1] 242 wys@DESKTOP-2OU3HRV:~/mycode/day09$ pid = 242,s = parent pid = 243,s = child pspid = 242,s = parent pid = 243,s = child PID TTY TIME CMD 11 tty1 00:00:00 bash 242 tty1 00:00:00 main 243 tty1 00:00:00 main 244 tty1 00:00:00 ps wys@DESKTOP-2OU3HRV:~/mycode/day09$ pid = 242,s = parent pid = 243,s = child ps PID TTY TIME CMD 11 tty1 00:00:00 bash 242 tty1 00:00:00 main 243 tty1 00:00:00 main 245 tty1 00:00:00 ps wys@DESKTOP-2OU3HRV:~/mycode/day09$ pid = 242,s = parent pspid = 242,s = parent PID TTY TIME CMD 11 tty1 00:00:00 bash 242 tty1 00:00:00 main 243 tty1 00:00:00 main246 tty1 00:00:00 ps wys@DESKTOP-2OU3HRV:~/mycode/day09$ pid = 242,s = parent pid = 242,s = parent
父进程先于子进程结束,子进程进入僵尸状态!
243 tty1 00:00:00 main
2.父进程通过调用wait()完成处理僵尸进程
查看**wait()**命令使用方法
pid_t wait(int *status);
WIFEXITED(status) 这个宏用来指出子进程是否为正常退出的,如果是,它会返回一个非零值。(请注意,虽然名字一样,这里的参数status并不同于wait唯一的参数–指向整数的指针status,而是那个指针所指向的整数,切记不要搞混了。)
WEXITSTATUS(status) 当WIFEXITED返回非零值时,可以用这个宏来提取子进程的返回值,如果子进程调用exit(5)退出,WEXITSTATUS(status)就会返回5;
父进程调用wait(),代码如下:
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 8 int main() 9 { 10 char* s = NULL; 11 int n = 0; 12 13 pid_t pid = fork(); 14 assert(pid != -1); 15 16 if(pid == 0) 17 { 18 s = "child"; 19 n = 3; 20 } 21 else 22 { 23 s = "parent"; 24 n = 7; 25 int val = 0; 26 wait(&val); 27 if(WIFEXITED(val)) 28 { 29 printf("val = %dn",WEXITSTATUS(val));//如果子进程未结束,那么wait会阻塞 30 } 31 } 32 33 for(int i = 0;i < n;i++ ) 34 { 35 printf("pid = %d,s = %sn",getpid(),s); 36 sleep(1); 37 38 } 39 exit(3);//退出程序,并返回值3 40 }
编译运行:
wys@DESKTOP-2OU3HRV:~/mycode/day09$ gcc -o main main.c wys@DESKTOP-2OU3HRV:~/mycode/day09$ ls main main.c wys@DESKTOP-2OU3HRV:~/mycode/day09$ ./main pid = 129,s = child pid = 129,s = child pid = 129,s = child val = 3 pid = 128,s = parent pid = 128,s = parent pid = 128,s = parent pid = 128,s = parent pid = 128,s = parent pid = 128,s = parent pid = 128,s = parent



