fork函数_Linux中子进程回收函数:wait和waitpid
图控大叔
构图传递思想
阅读从未如此简单!!!
01
前言
在进程的开发中,我们常常需要创建子进程来实现进程的“分身”,但是子进程执行完任务之后,需要父进程对其进行资源回收,否则该子进程将变成僵尸进程。那么父进程对子进程的资源回收所用到的函数则有我们今天的主角:wait和waitpid。
02
函数讲解
wait()函数说明
wait函数
需要包含头文件#include #include
函数原型pid_t wait (int * status);
参数说明:1、如果父进程需要知道子进程结束时候的状态值.则可以填充参数 如: int status; //创建子进程及相应判断 printf("wait(&status) is %d\n",wait(&status));2、如果父进程不需要知道子进程结束时候的状态值.则可以填充NULL 如: int status; //创建子进程及相应判断 printf("wait(NULL) is %d\n",wait(NULL));
返回值 1、 -1 ---》该子进程不存在 2、 子进程pid
其他说明1、wait函数的调用暂时停止目前进程的执行, 直到有信号来到或子进程结束2、如果同时创建了多个子进程,并且这些子进程都有调用退出函数,如:exit 哪个子进程先介绍,wait就先返回哪个子进程的pid值 (小编做了好多次测试,发现都是其他一样效果,后来在老师的指导下才纠正了这个思维定式的问题)
waitpid()函数说明
waitpid函数
需包含头文件#include #include
函数原型pid_t waitpid(pid_t pid, int * status, int options);
参数说明: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、还有其他情况,小编可能不知道
01
图片补充
03
代码
参考测试代码
#include #include
int main(int argc,const char **argv){ pid_t cpid[2]; int status;
cpid[0] = fork();
if(cpid[0] == -1) { perror("进程1创建失败\n"); return -1; } else if(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());
} return 0;}
04
留个问题
exit函数让调用者所对应进程结束,那么exit函数有负责进程资源的回收吗?答案是没有。exit和wait有什么不一样?当然有,自己总结!
05
结尾
本次关于Linux环境下子进程内存资源的回收所涉及的部分函数:wait和waitpid就分享到这里,如有纰漏,希望不吝赐教!谢谢阅读!
fork函数_Linux中子进程回收函数:wait和waitpid相关推荐
- 函数简介篇——进程创建函数:system()
说明: 本文章旨在总结备份.方便以后查询,由于是个人总结,如有不对,欢迎指正:另外,内容大部分来自网络.书籍.和各类手册,如若侵权请告知,马上删帖致歉. QQ 群 号:513683159 [相 ...
- linux函数脚本,linux 函数_linux常用脚本和函数
摘要 腾兴网为您分享:linux常用脚本和函数,自动刷宝,英语字典,携程,享家等软件知识,以及智慧人社app,安卓终端,vdhcoapp,matebook管家,钦州智慧党建,商户号系统,税务app,济 ...
- 剖析SGI STL空间配置器(deallocate内存回收函数和reallocate内存扩充函数)
剖析SGI STL空间配置器(deallocate内存回收函数和reallocate内存扩充函数) deallocate内存回收函数 deallocate函数的定义: static void deal ...
- 详解可重入函数与不可重入函数
C/C++ 中的可重入函数与不可重入函数 引言 在编程语言发展的历程中,"函数"的概念无疑是最历史中最伟大的发明之一.简单来说,函数是完成指定功能的代码集合. 函数的基本样式: i ...
- wait/waitpid函数与僵尸进程、fork 2 times
一.僵尸进程 当子进程退出的时候,内核会向父进程发送SIGCHLD信号,子进程的退出是个异步事件(子进程可以在父进程运行的任何时刻终止) 子进程退出时,内核将子进程置为僵尸状态,这个进程称为僵尸进程, ...
- 父进程回收子进程之wait()函数使用解读
1.wait的工作原理 (1)子进程结束时,系统向其父进程发送SIGCHILD信号 (2)父进程调用wait函数后阻塞 (3)父进程被SIGCHILD信号唤醒,然后去回收僵尸子进程 (4)父子进程之间 ...
- 进程创建函数fork()和vfork()
Linux下使用fork()创建一个新的进程,该函数不需要参数,返回值是一个进程id.对于不同的对象,分别是:新建的子进程id(返回给父进程),0(返回给创建的子进程)或者-1(子进程创建失败,返回给 ...
- c++中的fork函数_linux c语言 fork() 和 exec 函数的简介和用法
linux c语言 fork() 和 exec 函数的简介和用法 假如我们在编写1个c程序时想调用1个shell脚本或者执行1段 bash shell命令, 应该如何实现呢? 其实在<stdli ...
- 关于 Linux fork()进程创建函数 的 执行方式 返回值 lockf锁和并发 控制创建顺序 的探索
文章目录 BEGIN Demo 1 - 了解fork执行方式 code & result comprehension Demo 2 - fork的返回值研究 code & result ...
- 6进程原语:wait()和waitpid()函数
1 wait/waitpid 僵尸进程: 子进程退出,父进程没有回收子进程资源(PCB),则子进程变成僵尸进程 孤儿进程: 父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为1号 进 ...
最新文章
- PHP之使用网络函数和协议函数
- android广播接收器
- 工作日志之个人统计篇
- 使用plsql developer 创建用户
- python常用运维模块_python常用模块之一
- (原创)c#学习笔记08--面向对象编程简介02--OOP技术05--运算符重载
- css less 不要作用到子对象_使用Less实现网站主题切换
- android原生调用nextjs方法,详解使用Next.js构建服务端渲染应用
- JavaRabbitmq笔记-Rabbitmq自定义头(Properties中的headers)
- WIN7安装MTK驱动(系统找不到指定文件!解决方案)
- 一些常用软件镜像地址
- NPOI Word 原有表格增加一行
- 2022芒果TV算法赛_用户下一个观看视频预测_baseline_CF召回YoutubeDNN
- 前端页面直接根据URL链接生成二维码【亲测可用】
- 【信号处理】什么是基线漂移/趋势项?如何消除?
- 分组密码算法与DES算法
- csgo调哪个会流畅_CSGO:怎样提高游戏帧数,让画面变得更流畅?这些设置可以考虑一下...
- 基于VS2017+OpenCV,C++搭建NanoDet-Plus轻量级目标检测模型并训练(二)
- 获取dingding审批实例
- 在游戏上第3部分完美的信息游戏
热门文章
- 【TWVRP】基于matlab遗传算法求解带时间窗+带充电桩的无人机巡检路径规划问题【含Matlab源码 YC001期】
- 【细胞分割】基于matlab GUI生物细胞计数【含Matlab源码 758期】
- 【图像检索】基于matlab GUI KNN图像检索【含Matlab源码 267期】
- ai转型指南_穿越AI转型的转折点
- mysql查看enum和set值_mysql中的enum和set类型_MySQL
- 线性代数 前五章知识点梳理总结
- php中用get和post传值时的用法 $_GET[], $_POST[]
- angular集成websocket_angular使用 websocket,少点套路,多一点真诚
- rant c语言头文件,用CGIC库来开发CGI程序
- mysql的底层运行原理,【数据库】震惊!!MySQL的底层原理竟然是这样