Linux进程控制(下)

目录

进程虚拟地址空间

虚拟地址

写时拷贝

进程程序替换

替换原理

替换函数

1.execl

2.execlp

3. execle

4.execv

5.execvp​

6.execve

 子进程进行程序替换

进程虚拟地址空间

虚拟地址

在学习进程程序替换之前我们先来了解一下进程虚拟地址空间,这样有利于理解进程替换。先来看下面一段代码:

这段代码看起来很奇怪,子进程和父进程打印出来的g_a地址相同,值却不同。我们的理解一直是同一块地址的数据不可能不一样,其实并没有错,那么问题出在哪里?其实在我们看到的地址并不是真真实的地址,在Linux中这种地址称为虚拟地址!操作系统负责将虚拟地址转化成真正的物理地址。

操作系统会给每一个进程分配4G的虚拟内存(32位操作系统),这些虚拟内存并不保存数据,当需要保存数据时,才分配真正的物理内存,通过页表进行映射,如下图:

写时拷贝

当父进程使用fork()创建出子进程时,内核做:

 

通常情况下,父子进程代码共享,数据共享,当任意一方试图写入,便以写时拷贝的方式各自一份副本。

进程程序替换

替换原理

fork 创建子进程后执行的是和父进程相同的程序 ( 但有可能执行不同的代码分支 ), 子进程往往要调用一种 exec 函数 以执行另一个程序。当进程调用一种exec 函数时 , 该进程的用户空间代码和数据完全被新程序替换 , 从新程序的启动 例程开始执行。调用exec 并不创建新进程 , 所以调用 exec 前后该进程的 id 并未改变。

替换函数

有多种以 exec 开头的函数 , 统称 exec 函数,这些函数都可以用作进程程序替换。下面来介绍这六个函数:

1.execl

操作系统中的命令其实也是可执行程序,我们使用"pwd"命令来测试一下execl()函数,先使用命令:which pwd 找到"pwd"可执行程序的路径:

就接下来姐可以测试这个函数了: 

 代码执行后的现象说明此时进程程序替换成功。

2.execlp

 代码测试:

 可以看到此时没有带路径,也成功了。为什么此时不带路径也可以替换成功呢?

PATH环境变量中有/usr/bin/这个路径。 

3. execle

这个函数比execl多了一个参数envp[],它的意思是:调用该函数时需要自己组织环境变量 ,其他参数和execl一样。来看以下代码:

以上代码的作用是获取获取环境变量PATH。此时我们来测试execle()函数:

解释一下environ:每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串 ,environ指向数组第一个元素。,如下图:

如果把test.c中的代码做出以下更改:

 那么进程替换到执行get_env时就会执行失败,这是因为将get_env本来的环境变量替换为了NULL,这样getenv()函数就拿不到相应的值了。

所以:在使用execle()时需要自己组织环境变量。

4.execv

此函数的第二个参数是一个字符指针数组, 意思就是将命令行参数组织成字符指针数组的形式,然后进行参数传递。如下代码:

可以发现这个函数和execl()函数的不同点就是把缺省参数改成了字符指针数组。

5.execvp

 这个函数和execlp()的不同点就是将缺省参数改成了字符指针数组。

6.execve

 这个函数和execle()的不同点就是将缺省参数改成了字符指针数组。

事实上只有 execve 是真正的系统调用 , 其它五个函数最终都调用 execve, 所以 execve man 手册 第 2节, 其它函数在 man 手册第 3 节。

 子进程进行程序替换

学习完了以上函数,我们试着使用子进程来进行进程程序换,父进程等待子进程。代码如下:

运行结果如下:

 说明子进程进程程序替换成功。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值