Linux进程控制(2)(进程程序替换1)

目录

续--上一章

1.WIFEXITED && WEXITSTATUS

2.非阻塞等待

进程程序替换

1.先观代码 && 现象

2.原理解释

3.将代码改成多进程版

4.使用所有的替换方法,并且认识函数参数的含义


续--上一章

1.WIFEXITED && WEXITSTATUS

若需要知道退出码的话,还需要对status进行相应的位操作,那那些不懂操作的人该怎么办呢?

第一个 WIFEXITED 返回真时,则代表子进程正常退出,这时的 WEXITSTATUS 返回的就是子进程的退出码:

等待是必须的,但获取子进程的退出信息不是必须的,有时候如果不需要,则int *status输入NULL即可

如果想知道退出信号,就拿位操作去做,一般来说,对于程序员来讲,你只需要关注最终任务完成没有,若是出异常了,那就需要调试了,调试的时候按照自己的动作来调就行了

2.非阻塞等待

如果子进程没有退出,而父进程在进行执行waitpid进行等待时,则会发生阻塞等待 -- 进程阻塞了

即在等待某种条件发生(子进程退出)

在这种阻塞时,父进程其他事情什么都没干

pid_ t waitpid(pid_t pid, int *status, int options);

当options的为 WNOHANG 时,将会进行非阻塞等待

非阻塞等待(本质就是循环检测子进程的状态)就是允许父进程做一些其他的事情

返回值ret

ret > 0 :等待成功了,子进程退出了,并且父进程回收成功

ret < 0 :等待失败了

ret == 0 :检测是成功的,只不过子进程还没退出,需要你下一次进行重复等待

非阻塞等待的时候 + 循环 = 非阻塞轮询

代码测试:

进程程序替换

1.先观代码 && 现象

代码:

现象:

让我们(进程)用exec*(exec系列)的函数,执行起来新的程序

2.原理解释

进程 =  内核数据结构 + 代码和数据

本质上是将当前进程的代码和数据进行替换的一种技术

进程的程序替换并没有创建新的进程!!(该过程并没有把PCB 页表 地址空间 ... 重建

站在被替换进程的角度:本质就是这个程序被加载到内存了!
怎么加载?exec* 类似于一种Linux上的加载函数

那么对于这个运行结果,为什么下面这条语句未被执行呢

exec*系列的函数,执行完毕之后,后续的代码不见了,因为被替换了


execl函数的返回值可以不关心了。只要替换成功,就不会向后继续运行,只要继续运行了,一定是替换失败了!

3.将代码改成多进程版

fork创建子进程,让子进程自己去替换

创建子进程,让子进程完成任务:

1. 让子进程执行父进程代码的一部分

2. 让子进程执行一个全新的程序

ls指令 在子进程中进行覆盖代码和数据时,也要进行写时拷贝(代码和数据都要)

既然exec* 可以替代系统指令,就也可以替换其他指令已经各种可执行程序

4.使用所有的替换方法,并且认识函数参数的含义

l:list . 列表

path:我们要执行的程序,需要带路径(即怎么找到这个程序,你得告诉我)

后面的参数:在命令行中怎么执行,你就怎么传参

命令行 : $ ls -a -l

execl("/usr/bin/ls", "ls", "-a", "-l", NULL);

参数必须以NULL结尾

V:vector(动态数组)

和execl类似,只不过是将后面的参数放入数组

P:用户可以不传要执行文件的路径(但是文件名要传),直接告诉exec*,我要执行谁就行

本质就是会在环境变量PATH中进行查找这个名字

e:environment 环境变量

testexec.c:

mypragma.c:

运行:

这就和以前的命令行参数表和环境变量表一样,在父进程中本身会存在这两张表(这里的两张表是我们自定义的),会传递给子进程

但是在父进程本身就会有一批环境变量,从bash来:

即最后一个参数的意义是整体替换所有的环境变量!

1.用全新的给子进程
2.用老的环境变量给子进程, environ

3.老的环境变量稍微修改,给子进程(putenv操作可以新增环境变量)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值