图控大叔
构图传递思想
阅读从未如此简单!!!
01
前言
在进程的开发中,我们常常需要创建子进程来实现进程的“分身”,但是子进程执行完任务之后,需要父进程对其进行资源回收,否则该子进程将变成僵尸进程。那么父进程对子进程的资源回收所用到的函数则有我们今天的主角:wait和waitpid。
02
函数讲解
wait()函数说明
需要包含头文件 #include #include 函数原型 pid_twait (int* status); 参数说明: 1、如果父进程需要知道子进程结束时候的状态值.则可以填充参数 如: intstatus; //创建子进程及相应判断 printf("wait(&status) is %d\n",wait(&status)); 2、如果父进程不需要知道子进程结束时候的状态值.则可以填充NULL 如: intstatus; //创建子进程及相应判断 printf("wait(NULL) is %d\n",wait(NULL)); 返回值 1、 -1---》该子进程不存在 2、 子进程pid 其他说明 1、wait函数的调用暂时停止目前进程的执行, 直到有信号来到或子进程结束 2、如果同时创建了多个子进程,并且这些子进程都有调用退出函数,如:exit 哪个子进程先介绍,wait就先返回哪个子进程的pid值 (小编做了好多次测试,发现都是其他一样效果,后来在老师的指导下才纠正了这个思维定式的问题)wait函数
waitpid()函数说明
需包含头文件 #include #include 函数原型 pid_twaitpid(pid_tpid, int* status, intoptions); 参数说明: pid: pid<-1等待进程组识别码为 pid 绝对值的任何子进程. pid=-1等待任何子进程, 相当于 wait(). pid=0等待进程组识别码与目前进程相同的任何子进程. (和wait()一样) pid>0等待任何子进程识别码为 pid 的子进程. 说明:pid 乱填,该进程组内没有此pid的子进程,会返回-1 status: 用法和wait一样 options: 一般填0,有以下其他种选择,小编还没有弄懂,以后弄懂了再补充 其他选择为: WNOHANG 如果没有任何已经结束的子进程则马上返回, 不予以等待. WUNTRACED 如果子进程进入暂停执行情况则马上返回, 但结束状态不予以理会. 子进程的结束状态返回后存于 status, 底下有几个宏可判别结束情况 WIFEXITED(status) 如果子进程正常结束则为非 0值. WEXITSTATUS(status) 取得子进程 exit()返回的结束代码, 一般会先用 WIFEXITED 来判断是否正常结束才能使用此宏. WIFSIGNALED(status) 如果子进程是因为信号而结束则此宏值为真 WTERMSIG(status) 取得子进程因信号而中止的信号代码, 一般会先用 WIFSIGNALED 来判断后才使用此宏. WIFSTOPPED(status) 如果子进程处于暂停执行情况则此宏值为真. 一般只有使用 WUNTRACED 时才会有此情况. WSTOPSIG(status) 取得引发子进程暂停的信号代码, 一般会先用 WIFSTOPPED 来判断后才使用此宏. 返回值: 和wait一样。 其他说明: waitpid 1、如果所填pid所对应子进程不存在,则立即返回-1 2、如果所填pid存在,但是一直不退出,则一直等待 该子进程不退出为可能 1、调用了pause() 2、vfork函数创建的子进程未调用exit 因为fork函数创建的子进程调用return或者exit都可以退出 3、一直处于while循环中 4、还有其他情况,小编可能不知道waitpid函数
01
图片补充
03
代码
参考测试代码
#include intmain(intargc,constchar**argv){ pid_tcpid[2]; intstatus; cpid[0] = fork(); if(cpid[0] == -1) { perror("进程1创建失败\n"); return-1; } elseif(cpid[0]==0) { printf("client1 id %d father id %d\n",getpid(),getppid()); //sleep(0); //pause(); exit(0); } cpid[1] = fork(); //printf("开始 2\n"); if(cpid[1] == -1) { perror("进程2创建失败\n"); return-1; } if(cpid[1]==0) { printf("client2 id %d father id %d\n",getpid(),getppid()); //sleep(2); //pause(); //return 0; exit(0); } else{ //wait(&status); //printf("wait is %d\n",wait(&status));//首先结束第一个创建的子程序 //printf("wait is %d\n",wait(&status)); //printf("wait(&status) is %d\n",wait(&status)); printf("wait is %d\n",waitpid(cpid[1],&status,WIFEXITED(status))); //printf("wait cpid[1] %d is %d\n",cpid[1],waitpid(cpid[1],&status,0)); printf("father id is %d\n",getpid()); } return0; }#include
04
留个问题
exit函数让调用者所对应进程结束,那么exit函数有负责进程资源的回收吗?答案是没有。exit和wait有什么不一样?当然有,自己总结!
05
结尾
本次关于Linux环境下子进程内存资源的回收所涉及的部分函数:wait和waitpid就分享到这里,如有纰漏,希望不吝赐教!谢谢阅读!