目录
引言:创建一个进程,必然是要这个创建出来的进程去完成某种任务,该进程必须把任务的完成结果返回给其父进程,这就像打游戏 你接受了一个任务,任务完成后,还必须回去告诉发布任务的人,我完成这个任务啦,奖励才会到你的手。
进程退出结果是由退出信号和退出码两种状态共同决定的。
?????????????????????????(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;
}
}