当前位置: 首页 > news >正文

《Linux篇》进程等待(wait、waitpid)与进程程序替换(exec等接口)

文章目录

    • 1.进程等待的必要性
    • 2.进程等待的方法
      • 2.1 wait方法
      • 2.2 waitpid方法
    • 3.进程程序替换
      • 3.1 进程程序替换的原理
      • 3.2 进程程序替换示例
      • 3.3 其他接口

1.进程等待的必要性

为什么要有进程等待,也就是进程等待的必要性:

  1. 之前讲过,⼦进程退出,⽗进程如果不管不顾,就可能造成 ‘僵⼫进程’ 的问题,进⽽造成内存泄漏。
  2. 另外,进程⼀旦变成僵⼫状态,那就⼑枪不⼊,“杀⼈不眨眼”的kill -9 也⽆能为⼒,因为谁也没有办法杀死⼀个已经死去的进程。
  3. 最后,⽗进程派给⼦进程的任务完成的如何,我们需要知道。如,⼦进程运⾏完成,结果对还是不对,或者是否正常退出。
  4. ⽗进程通过进程等待的⽅式,回收⼦进程资源(必要的),获取⼦进程退出信息(可选的)。

进程等待就是让父进程通过等待的方式,回收子进程的PCB,如果需要,可以获取子进程的退出信息!!!

2.进程等待的方法

2.1 wait方法

#include<sys/types.h>
#include<sys/wait.h>pid_t wait(int* status);
返回值:
成功返回被等待进程pid,失败返回-1。
参数:
输出型参数,获取⼦进程退出状态,不关⼼则可以设置成为NULL

对于status这个参数不重要,之后我们主要使用waitpid方法。
在这里插入图片描述
示例:
在这里插入图片描述
在这里插入图片描述

2.2 waitpid方法

pid_ t waitpid(pid_t pid, int *status, int options);
返回值:当正常返回的时候waitpid返回收集到的⼦进程的进程ID;如果设置了选项WNOHANG,⽽调⽤中waitpid发现没有已退出的⼦进程可收集,则返回0;如果调⽤中出错,则返回-1,这时errno会被设置成相应的值以指⽰错误所在;
参数:pid:Pid=-1,等待任⼀个⼦进程。与wait等效。Pid>0.等待其进程ID与pid相等的⼦进程。status: 输出型参数WIFEXITED(status): 若为正常终⽌⼦进程返回的状态,则为真。(查看进程是否是正常退出)WEXITSTATUS(status): 若WIFEXITED⾮零,提取⼦进程退出码。(查看进程的退出码)options:默认为0,表⽰阻塞等待WNOHANG: 若pid指定的⼦进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该⼦进程的ID。

对于status参数说明:

  • wait和waitpid,都有⼀个status参数,该参数是⼀个输出型参数,由操作系统填充
  • 如果传递NULL,表⽰不关⼼⼦进程的退出状态信息。否则,操作系统会根据该参数,将⼦进程的退出信息反馈给⽗进程
  • status不能简单的当作整形来看待,可以当作位图来看待,具体细节如下图(只研究status低16⽐特位)

waitpid的第二个参数status与wait的参数一样,它是一个输出型参数,它是一个int类型,高16位不考虑,有价值的是低16位。这里的status不仅仅是退出码,如果是正常退出的,他的低16位的高8位是退出码,低8位全为0。一般而言,子进程的退出码取值范围是[0,255]。如果进程是异常退出的,被信号杀掉,进程的退出码没有意义,低16位中的低7位表示的是终止信号,即被几号信号所杀,还有一个core dump标志在后面的信号部分会讲解到。
在这里插入图片描述
如果进程出现了异常呢?kil -l 可以看到所有的信号信息
在这里插入图片描述
上图的退出码和退出信号写反了。
在这里插入图片描述
在这里插入图片描述
补充:对于上面所说的WIFEXITED(status)就是提取exit_signal的值,也就是查看进程是否正常推出的。如果非0表示的就是正常结束,如果不是0,则进程异常。WEXITSTATUS(status)是用来查看进程的退出码的,若WIFEXITED⾮零,提取⼦进程退出码。
在这里插入图片描述
阻塞等待与非阻塞等待

对于上面的WNOHANG参数表示非阻塞等待(非阻塞轮询方案)。
在这里插入图片描述

  • 非阻塞等待:不会因为子进程条件没有就绪而阻塞,而是立即返回。本质是检测子进程状态,子进程没有结束,会立即返回,并且会轮询等待。非阻塞轮询等待不会卡住父进程,父进程可以在等待的时间间隙自己就可以做其他事情了,所以说非阻塞等待更高效一点。
  • 阻塞等待:父进程会一直等,不会做别的事情。
    在这里插入图片描述
    如下,当父进程在等待子进程时就可以做一些其他事情了:
    在这里插入图片描述

3.进程程序替换

fork可以让父子执行不同的代码段,让子进程执行父进程代码的一部分。如果我们想让子进程执行一个全新的代码该怎么办呢?fork之后,代码共享,数据“共享”(写时拷贝)。一个进程要想执行一个不同的程序,调用exec函数。 子进程有自己的代码和数据,是一个真正独立的进程!!!

3.1 进程程序替换的原理

在这里插入图片描述

3.2 进程程序替换示例

在这里插入图片描述
一共有六个程序替换的接口,我们先看简单易一点的execl
在这里插入图片描述
对于可变参数来说,必须以NULL结尾:
在这里插入图片描述
示例:
在这里插入图片描述
本质其实就是把所有的变量入栈,再取出的过程!!!

execl函数示例:
在这里插入图片描述
在这里插入图片描述
我们可以看到execl结束后没有打印:进程退出!!!因为我们替换了,我们的进程已经执行另一个程序的代码了。如果执行成功,不会有返回值,后续代码,不再执行!如果执行失败,返回值为-1,会执行后续代码!!! 对于execXiamen的函数,只要返回,必定失败!

这样我们就可以替换子进程的代码和数据,子进程会执行一个全新的程序,不会影响父进程,因为进程必须具有独立性!!!(父子代码共享,数据写时拷贝)如果代码被替换,也要进行写时拷贝

父子版本的程序替换:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3 其他接口

在这里插入图片描述
在这里插入图片描述
示例:

#include <unistd.h>
int main()
{char *const argv[] = {"ps", "-ef", NULL};char *const envp[] = {"PATH=/bin:/usr/bin", "TERM=console", NULL};execl("/bin/ps", "ps", "-ef", NULL);// 带p的,可以使⽤环境变量PATH,⽆需写全路径execlp("ps", "ps", "-ef", NULL);// 带e的,需要⾃⼰组装环境变量execle("ps", "ps", "-ef", NULL, envp);execv("/bin/ps", argv);// 带p的,可以使⽤环境变量PATH,⽆需写全路径execvp("ps", argv);// 带e的,需要⾃⼰组装环境变量execve("/bin/ps", argv, envp);exit(0);
}

在这里插入图片描述
对于上面的六个接口,底层都是调用的execve,他是个系统调用,只是传参形式不同,来满足我们不同的应用场景。
在这里插入图片描述

http://www.dtcms.com/a/555467.html

相关文章:

  • 福州网站改版宝塔面板做网站绑定域名
  • 网站上的图片带店面是怎么做的盘搜搜
  • 上海品划网络做网站注册公司流程和费用2020
  • 下载类网站 建设方案台州企业网站模板建站
  • 网站一直显示建设中网站建设从哪入手
  • 谁做的四虎网站是多少钱甘肃网站seo哪家公司好
  • 海外网站建设平台个性化网站模板
  • 上海网站搭建公司哪家好网站建设备案书模板
  • 深圳网站设计招聘山东网站建设哪家专业
  • C++函数:从入门到工程实战
  • 找外包做网站不给代码北京网站建设华网天下科技
  • 网站每天更新的内容是内链吗手工艺品外贸公司网站建设方案
  • 免费制作自己的微网站wordpress 静态缓存
  • 广州网站开发定制传奇电脑版哪个好玩
  • 河南专业建网站网站公司做文员
  • 已有网站开发app终端网站升级维护要多久
  • 北京企业网站建设公司培训网站建设公司排名
  • 云主机开网站教程木工支模价格明细表
  • 音响厂家东莞网站建设网站篡改搜索引擎js
  • 有什么网站是专做婚礼素材的网站维护项目
  • 1个服务器可以做多少个网站四川建设人才网证书查询
  • 2017酷站推荐网站外包网易
  • 网站收录一般多久wordpress flat 下载
  • 上海网站建设收费标准敏感词过滤wordpress
  • Linux中动态修改页面映射属性函数change_page_attr的实现
  • 网站建设流程精英网站欢迎页面flash
  • html5网站开发实例教程外贸建站推广多少钱
  • 建安证查询网站网络营销一个月能挣多少钱
  • 食品网站制作建设人行官方网站
  • 郴州公司做网站wordpress添加分类图片尺寸