一.正常退出
1.main函数调用return
2.进程调用exit(),标准c库
3.进程调用_exit()或者_Exit(),属于系统调用
二.异常退出
1.调用abort
2.当进程收到某些信号时,如ctrl+c
3.最后一个线程对取消(cancellation)请求做出响应。
三.父进程等待子进程退出
***为什么要等待子进程退出?
首先创建子进程的目的是让其干活,得知道子进程是否完成这件事,所以等待子进程退出就是收集子进程得状态,也就是是否干完了或者干得怎么样。
***子进程状态不被收集则变成僵尸进程
1.wait()函数api:
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *wstatus);
pid_t waitpid(pid_t pid, int *wstatus, int options);
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
2.检查wait和waitpid所返回的终止状态的宏
宏 | 说明 |
---|---|
WIFEXITED(status) | 若为正常终止子进程返回的状态,则为真。对于这种情况可执行WEXITSTATUS(status),取子进程传送给exit,_exit或_Exit参数的低8位 |
WIFSIGNALED(status) | 若为异常终止子进程返回的状态,则为真(接倒一个不捕捉的信号)。对于这种情况,可执行WTERMSIG(status),取子进程终止的信号编号。另外,有些实现(非Single UNIX Specification)定义宏WCREDUMP(status),若已产生终止进程的core文件,则它返回为真 |
WIFSTOPPED(status) | 若为当前暂停子进程的返回的状态,则为真,对于这种情况,可执行WSTOPSIG(status),取使子进程暂停的信号编号 |
WIFCONTINUED(status) | 若在作业控制暂停后已经继续的子进程返回了状态,则为真。(POSIX.1的XSI扩展,仅用于waitpid。) |
3.编程实例
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
// pid_t fork(void);
int main()
{
pid_t pid;
pid=vfork();
int cnt;
int status = 0;
if(pid>0)
{
wait(&status);
printf("child status =%d\n",WEXITSTATUS(status));
while(1)
{
printf("this is father fork\n");
sleep(1);
printf("cnt=%d\n",cnt);
}
}
else if(pid==0)
{
cnt=0;
while(1)
{ cnt++;
printf("this is child fork\n");
sleep(1);
if(cnt==3)
{
exit(3);
}
}
}
}
4.执行结果
******父进程在等待子进程的过程中,即wait()函数,父进程一直在阻塞,而子进程一直执行。
二.waitpid()等待进程
pid_t waitpid(pid_t pid, int *wstatus, int options);
1.对于waitpid函数中pid参数的作用解释如下:
pid == -1 等待任一子进程,就这一方面而言,waitpid与wait等效。
pid > 0 等待其进程ID与pid相等的子进程。
pid == 0 等待其组ID等于调用进程组ID的任一子进程
pid < -1 等待其组ID等于pid绝对值的任一子进程。
2.waitpid的option常量
常量 | 说明 |
---|---|
WCONTINUED | 若实现支持作业控制,那么由pid指定的任一子进程在暂停后已经继续,但其状态未报告,则返回其状态(POSIX.1的XSI的扩展) |
WNOHANG | 若由pid指定的子进程并不是立即可用的,则waitpid不可阻塞,则其返回值为0 |
WUNTRACED | 若某实现支持作业控制,而由pid指定的任一子进程已处于暂停状态,并且其状态自暂停以来还未报告过,则返回其状态。WIFSTOPPED宏确定返回值是否对应于一个暂停子进程 |
3.编程实现
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
// pid_t fork(void);
int main()
{
pid_t pid;
pid=vfork();
int cnt;
int status = 0;
if(pid>0)
{
//wait(&status);
waitpid(pid,&status,WNOHANG);
printf("child status =%d\n",WEXITSTATUS(status));
while(1)
{
printf("this is father fork\n");
sleep(1);
printf("cnt=%d\n",cnt);
}
}
else if(pid==0)
{
cnt=0;
while(1)
{ cnt++;
printf("this is child fork\n");
sleep(1);
if(cnt==3)
{
exit(3);
}
}
}
}
运行结果