Linux进程 -- wait/waitpid函数
来源:互联网 发布:乔丹各赛季数据 编辑:程序博客网 时间:2024/05/17 15:17
僵尸进程: 子进程退出,父进程没有回收子进程资源(PCB),则子进程变成僵尸进程。
孤儿进程: 父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为1号进程init进程。
wait/waitpid函数
函数原型:
#include <sys/types.h>#include <sys/wait.h>pid_t wait(int *status);pid_t waitpid(pid_t pid, int *status, int options);
参数pid:
pid < -1 回收指定进程组内的任意子进程pid = -1 回收任意子进程pid = 0 回收和当前调用 waitpid 一个组的所有子进程pid > 0 回收指定ID的子进程
一个进程在终止时会关闭所有文件描述符,释放在用户空间分配的内存,但它的PCB还保留着,内核在其中保存了一些信息:如果是正常终止则保存着退出状态,如果是异常终止则保存着导致该进程终止的信号是哪个。
(两函数功能)
这个进程的父进程可以调用wait或waitpid获取这些信息,然后彻底清除掉这个进程。
我们知道一个进程的退出状态可以在Shell
中用特殊变量$?
查看,因为Shell是它的父进程,当它终止时Shell调用wait
或waitpid
得到它的退出状态同时彻底清除掉这个进程。
如果一个进程已经终止,但是它的父进程尚未调用wait
或waitpid
对它进行清理,这时的进程状态称为僵尸(Zombie)进程。
任何进程在 刚终止时 都是僵尸进程,正常情况下,僵尸进程都立刻被父进程清理了,为了观察到僵尸进程,我们自己写一个不正常的程序,父进程fork
出子进程,子进程终止,而父进程既不终止也不调用wait清理子进程:
#include <unistd.h>#include <stdlib.h>int main(void){ pid_t pid=fork(); if(pid<0) { perror("fork"); exit(1); } if(pid>0) { /* parent */ while(1); } /*child */ return 0;}
编译及执行
yu@ubuntu:~/Linux/210/zombie$ gcc zombie.cyu@ubuntu:~/Linux/210/zombie$ ./a.out//阻塞
另开一终端,查看进程情况:
yu@ubuntu:~$ ps -aux |grep a.outyu 2715 94.4 0.0 2088 624 pts/1 R+ 23:54 1:10 ./a.outyu 2716 0.0 0.0 0 0 pts/1 Z+ 23:54 0:00 [a.out] <defunct>yu 2803 0.0 0.1 4532 1976 pts/18 S+ 23:55 0:00 grep --color=auto a.out
调用wait/waitpid
若调用成功则返回清理掉的子进程id,若调用出错则返回-1。
父进程调用wait或 waitpid时可能会:
阻塞(如果它的所有子进程都还在运行)。
带子进程的终止信息立即返回(如果一个子进程已终止,正等待父进程读取其终止信 息)。
出错立即返回(如果它没有任何子进程)。
wait和waitpid函数的区别是:
如果父进程的所有子进程都还在运行,调用wait将使父进程阻塞,而调用waitpid时如 果在options参数中指定WNOHANG可以使父进程不阻塞而立即返回0。
wait等待第一个终止的子进程,而waitpid可以通过pid参数指定等待哪一个子进程。
可见,调用wait和waitpid不仅可以获得子进程的终止信息,还可以使父进程阻塞等待子进 程终止,起到进程间同步的作用。
如果参数status
不是空指针,则子进程的终止信息通过这个参数传出,如果只是为了同步而不关心子进程的终止信息,可以将status
参数指定为NULL
。
waitpid
使用实例:
#include <sys/types.h>#include <sys/wait.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>int main(void){ pid_t pid; pid = fork(); if (pid < 0) { perror("fork failed"); exit(1); } if (pid == 0) { //son int i; for (i = 3; i > 0; i--) { printf("This is the child\n"); sleep(1); } exit(3); } else { //parent int stat_val; waitpid(pid, &stat_val, 0); if (WIFEXITED(stat_val)) printf("Child exited with code %d\n", WEXITSTATUS(stat_val)); else if (WIFSIGNALED(stat_val)) printf("Child terminated abnormally, signal %d\n", WTERMSIG(stat_val)); } return 0;}
编译及执行:
yu@ubuntu:~/Linux/210/waitpid$ gcc waitpid.cyu@ubuntu:~/Linux/210/waitpid$ ./a.outThis is the childThis is the childThis is the childChild exited with code 3
- Linux进程 -- wait/waitpid函数
- linux C进程 进程等待wait与waitpid函数
- linux 进程等待 wait 、 waitpid
- Linux进程学习---wait()和waitpid()函数
- linux waitpid/wait函数用法
- linux waitpid/wait函数用法
- Linux signal, wait, waitpid 函数
- 僵尸进程以及wait和waitpid函数
- 进程控制-wait()和waitpid()函数
- Linux--等待进程结束wait()和waitpid()
- Linux 进程之wait,waitpid讲解
- Linux进程相关,fork,wait,waitpid,WIFEXITED
- 【Linux】回收子进程—wait/waitpid
- linux系统编程之进程(四):wait/waitpid函数与僵尸进程、fork 2 times
- 【经典转载】Linux进程学习系列之五 等待进程结束wait()和waitpid()函数
- linux系统编程之进程(四):wait/waitpid函数与僵尸进程、fork 2 times
- 【Linux基础】wait和waitpid函数
- 【Linux编程】wait和waitpid函数
- hdoj5621KK's Point
- Spring10种常见异常解决方法
- Android音乐播放器高级开发
- apache commons io 可靠性报告
- #学习笔记#(39)JS随机颜色
- Linux进程 -- wait/waitpid函数
- ELK Stack搭建和使用中的一些小记录
- 2016.2.11
- Linux内核的起步
- Git远程操作详解
- 关于DreamWeaver CS6.0 + PhoneGap 之移动开发环境搭建
- 智慧北京开发第四天(上)
- 无所不知的BroadcastReceiver
- apache commons io 发行审查工具结果