目录
1.进程退出
1.1进程退出方式:
1.2进程退出函数
1.3退出码转化为错误描述
2.进程等待
2.1进程等待的必要性:
2.2进程等待方法waitpid
引言:创建一个进程,必然是要这个创建出来的进程去完成某种任务,该进程必须把任务的完成结果返回给其父进程,这就像打游戏 你接受了一个任务,任务完成后,还必须回去告诉发布任务的人,我完成这个任务啦,奖励才会到你的手。
进程退出结果是由退出信号和退出码两种状态共同决定的。
(1)代码运行完毕,结果正确。
(2)代码运行完毕,结果不正确。
(3)代码异常终止。
进程退出时必须先看退出信号,再看退出码。
因为退出信号异常,说明这个进程再执行的时候就已经出问题了,这个时候就没有必要看退出码了,过程错了,结果毫无意义,就好像我考试考了100分但是我作弊被发现了,这个100分就变了毫无意义。
void exit(int status)
return 0的本质就是把 0 传给exit,exit结束进程,退出码为0,exit(3)就是退出进程,退出码为3
每个错误码对应不同的错误信息利用char* strerror(int errnum)函数,将错误码转化为错误信息
strerror 返回值是char *直接用printf打印出来,就可以看到错误信息,errnum就是错误码。
(1)子进程退出后,会把自己的退出码,退出信号都放在task_struct (linux 的pcb)中,如果没有父进程把task_struct中的退出码和退出信 号 读 取, 这个子进程task_struct会一直存在内存中,就会造成僵尸 进 程问题,导致内存泄漏。
(2)父进程可以通过等待的方式,来获取子进程的退出信息,并且回收子进 程task_struct的空间。
pid_t waitpid(pid_t pid,int *status,int options);
返回值:(1)返回收集到子进程的pid
(2)调用出错返回-1
pid: (1)pid = -1 等待所有的子进程
(2) pid = (你想要等待子进程的pid)只会等待你想要的子进程
status: 这是一个输出型的参数,返回的是子进程的状态
status是一个整形变量,这个整形变量的前0-7位,8位表示退出码,7-15位,7位表示退 出信号 如果退出码和退出信号都为1 那么status的前15位为000 0001 0000 0001, status的值为2^8+2^0 = 257
获取退出码:status &0x7F
获取退出信号:(status >> 8)&0xFF
options: (1)options == 0 为阻塞等待,意思就是,只要子进程不退出,父进程就一直傻等着 什 么也不做。
(2)options == WNOHANG 意思是wait no hang 不在阻塞等待,waitpid如果子进程没结 束就返回0,结束了就返回子进程的pid,如果子进程没结束,我可以去干别的事情,怎 么 做到呢?代码仅供参考
基于轮询的非阻塞等待
while(true)
{ //假设要查询的子进程的pid为22345
int status = 0;
pid_t rid = waitpid(22345,&status,WNOHANG);
if(rid == 0)//子进程还没退出
{
//做别的事情
}
else if (rid > 0)//waitpid 等待成功了
{
printf("wait success rid:%d exitcode:%d exitsignal",rid,status&0x7F,(status>>8)&0xFF);
break;
}
}