僵尸进程:一个子进程在其父进程没有调用wait()或waitpid()的情况下退出。这个子进程就是僵尸进程。如果其父进程还存在而一直不调用wait,则该僵尸进程将无法回收,等到其父进程退出后该进程将被init回收。
孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为
孤儿进程。孤儿进程将被
init
进程
(
进程号为
1)
所收养,并由
init
进程对它们完成状态收集工
作。
******************************************************************************************************************************************************************
一、进程等待的函数 wait/waitpid
(1)wait
参数:通过它拿到子进程的终止状态,
如果不关心 ,
可将它设置为NULL,它是一个输出型参数。
子进程的退出码:status的次八位(status>>8)&0xff,
也可以用宏
WEXITSTATUS(status)
查看;
进程的终止情况:status的低八位(status&0xff),也可以用宏
WIFEXITED(status)查看;
当进程异常终止时,退出码无意义
返回值:成功->返回子进程的pid,失败->返回-1
功能:1、读取子进程退出状态;2、释放子进程的资源(PCB)
WEXITSTATUS(status)与
WIFEXITED(status)
宏解释:
WIFEXITED(status) :
1.
正常创建父子进程,子进程正常退出,父进程等待,并获取退出状
态
status
。调用该宏,查看输出结果(正常为非
0
,或
1
)。
2.
正常创建父子进程,子进
程
pause()
,父进程等待,并设置获取退出状态
status。
kill
杀掉子进程,调用该宏,查看
输出结果(结果为
0
)。
WEXITSTATUS(status) :
若
WIFEXITED
非零,返回子进程退出码,提取进程退
出返回值,如果子进程
exit(7),WEXITSTATUS(status)
就会返回
7.
请注意
,
如果进程不
是正常退出的
,
也就是说
,WIFEXITED
返回
0,
这个值就毫无意义
.
。
(2) waitpid
返回值:1、
当正常返回的时候
waitpid
返回收集到的子进程的进程
ID
;
2、如果设置了选项
WNOHANG,
而调用中
waitpid
发现没有已退出的子进程可收集
,
则返回
0
;
3、如果调用中出错
,
则返回
-1,
这时
errno
会被设置成相应的值以指示错误所在;
4、当
pid
所指示的子进程不存在
,
或此进程存在
,
但不是调用进程的子进程
,waitpid
就
会出错返回
,
这时
errno
被设置为ECHILD。
参数:
pid
: 1、p
id=-1,
等待任
一个子进程。与
wait
等效。
2、pid>0.
等待其进程
ID
为pid的子进程。
3、pid==0
等待其组
ID
等于调用进程组
ID
的任一个子进程。
4、pid<-1
等待其组
ID
等于
pid
绝对值的任一子进程。
status:
WIFEXITED(status) :
若为正常终止子进程返回的状态,则为真。(查看进程是
否是正常退出)
WEXITSTATUS(status) :
若
WIFEXITED
非零,提取子进程退出码。(查看进程
的退出码)
options:1、
WNOHANG :
若
pid
指定的子进程没有结束,则
waitpid()
函数返回
0
,调用waitpid的进程不会被阻塞,将继续执 行;
若正常结束,则返回该子进程的
ID
。
2、 options==0:
调用waitpid的进程会进行阻塞等待。
waiptpid提供了wait没有提供的三个功能:
1. waitpid
可等待一个特定的进程
2. waitpid
提供了一个
wait
的非阻塞版本
3. waitpid
支持作业控制
waitpid的使用例子:
子进程的执行流:(若不说明退出方式,它的退出方式默认为exit(0))
父进程的执行流:(因为是以非阻塞的方式等待子进程,在子进程没有退出时,waitpid的返回值一直都是0,所以要以循环的方式等待,直到waitpid的返回值为子进程的ID时,才等待成功)
******************************************************************************************************************************************************************
二、进程终止
(1)
进程终止的方式有
8
种,前
5
种为正常终止,后三种为异常终止:
1
从
main
函数返回;
2
调用
exit
函数;
3
调用
_exit
或
_Exit
;
4
最后一个线程从启动例程返回;
5最
后一个线程调用
pthread_exit
;
6
调用
abort
函数;
7
接到一个信号并终止;
8
最后一个线程对取消请求做出响应。
(2)exit与 _Exit,_exit的区别:
_exit
和
_Exit
立即进入内核,而
exit
则要先做一些清理
工作(调用执行各终止处理程序,关闭所有标准
I/O
流),再进入内核。
#include <stdlib.h>
void exit( int status );
void _Exit( int status );
#include <unistd.h>
void _exit( int status );
这三个函数用于正常终止一个程序,
三个函数所带的整
型参数称为终止状态或退出状态,如果
(
a
)调用这些函数不带参数;
(
b
)
main
函数中的
return
语句无返回值;
(
c
)
main
函数没有声明返回类型为整型;
则进程的终止状态是未定义
的。
main
函数返回一个整型值与用该值调用
exit
是等价的。