首页 > 进程程序替换

进程程序替换

引入进程程序替换的概念

一般在fork了一个子进程之后,子进程往往会调用exec函数组来执行其他的程序,因为我们的子进程不可能直接执行很多的功能,这个大家在以后的操作中会慢慢的体会到

程序替换的几个特点

  • 进程在使用exec函数族进程进程替换的时候,并没有创建一个新的进程,所以当前进程的进程ID并没有改变。exec函数族只是用磁盘上面的一个新程序替换了当前进程的正文段、数据段、堆段和栈段。
  • 调用exec函数族后,除非调用失败,否则没有返回值,并且调用失败之后,调用处之后的子进程的程序继续执行,如果调用成功,调用处之后的子进程将不再执行。
  • 当子进程调用exec函数族之后,不管成功与否,父进程依然可以正常执行的。

    下面我们想写一些程序来测试上面的例子
#include2 #include3 #include4 int main()5 {6     pid_t son = fork();7     if(son == 0)  //子进程8     {9         printf("i am son. my id is %d
",getpid());10         execl("/bin/ls","ls","-a","-n","-l",NULL);11         printf("调用exec函数失败
");12         exit(0);13     }14     else //父进程15     {16         printf("i am father
");17         sleep(5);18     }19 20     return 0;21 }

这里的结果如下图所示

这里写图片描述

我们来根据上面的结果来分析一下,这里执行完我们的替换函数之后,就没有执行printf(“执行完毕exec函数 ”);说明 我们上文中的第二个结论中“如果调用成功调用处之后的子进程将不再执行”是正确的。

接下来我们把程序改一下,测试一下如果调用失败是一个什么样的结果

我们这里只把exec函数中的”/bin/ls”改成”/bin/lsss”这样它在bin目录下肯定是找不到了,所以程序应该是调用失败的,失败了之后显示的结果是下图

这里写图片描述

这说明当我们exec函数失败后,调用的进程没有被替换,所以后面的程序继续执行

然后我们还需要看一下父进程的 结果是什么样的,从 上面的结果看不管子子进程调用exec函数结果如何,父进程始终正常运行。

接下来我们试了一下vfork的结果是什么样的,测试之后的结果还是什么上面的结论,当子进程调用exec函数族之后,不管成功与否,父进程依然可以正常执行的

大家可以下去尝试一下vfork,vfork的作用 是保证子进程先执行。

简析exec函数族

首先看一下exec函数族的定义

#include 2 extern char **environ;3 int execl(const char *path,const char *arg, ...);5 int execlp(const char *file, 6            const char *arg, ...);7 int execle(const char *path,8            const char *arg,9            ..., 
10            char * const envp[]);
11 int execv(const char *path,
12           char *const argv[]);
13 int execvp(const char *file, 
14            char *const argv[]);
15 int execve(const char *file,
16             char *const argv[],
17             char *const envp[]);

浅析进程替换函数

进程替换函数有六种分别是execl、execlp、execle和execv、execvp、execve,我们首先观察这几个函数会发现这些函数都是以exec开头的,由此我们称这些函数是exec函数族。

接下来又分为两类,一类是execl,一类是execv。前面三个是以execl开头,这个开头有一个特点就是在exec后面加上了l,我们发挥想象 可以想象到STL中的list,就是一个链表,这里可以理解为我们在使用这中类型的函数的时候是需要传入的一个可变的参数列表的。

这个可变参数列表实际上就是一些程序的一些可执行选项,比如我们在执行ls命令的时候,实际上就是在shell程序下进行了一次程序替换,在执行ls的时候我们可以给他它加上许多选项,比如ls -a -l等等。

另外就是execv,这个v可以让我们想起STL中的vector,就是线性表,就是我们在使用这个函数的时候需要传入的是一个数组。

再来解释一下带有p的函数,表示不需要加入替换程序的绝对路径或者是相对路径,不带p的就是要加入绝对路径或者是相对路径,另外还有就是带有e的函数,这个时候我们可以传入特定的环境变量。

接下来举例子来具体看看这些函数是如何使用,比如我们在父进程中创建了一个子进程,然后又在这个子进程中的合适位置调用了exec函数,那么这个时候就会发生程序替换

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

这里因为是一个execl函数,他没有带有p,所以我们第一个参数传递的是替换程序的绝对路径或者是相对路径,这里我门替换的函数是ls函数,它的绝对路径是”/bin/ls”,下面的那些事执行这个程序的一些选项,注意要以NULL结尾

execlp
execlp("ls","ls","-a","-l","-n",NULL)

加上这个p之后我们就不需要加上程序的路径了,execlp会自己搜索,这个时候有人就会问了,为什么还要写两次ls呢,这里第一个ls是我们需要执行的程序,第二个ls结合着后面的一些选项就是我们是要如何执行。

execv
char* _agrv[] = { "ls","-a","-n","-l",NULL};
execv("/bin/ls",_agrv);

其实这里很简单,我们无非就是把上面的那个函数的后面的选项加入到一个指针数组里面去了,这个就是execv函数组的意义,其他的两个函数这里就不解释了。

execle

这个函数我们需要传入特定的环境变量,这个留个悬念,大家自己网上搜索吧。

补充说明,上面替换的程序可以是大家自己写的程序哦…

更多相关:

  • 草色新雨中, 松声晚窗里。之前我们学习 Power Query 都是用鼠标就完成了很多复杂的操作。虽然 PowerQuery 已经将大部分常用功能内置成到功能区。基本能完成我们大部分的报表自动化功能。但是总有些复杂的或者个性化的问题是开发团队没有预先想到的,这时我们就需要学习 M 语言。一、M 语言在哪里?M语言的函数公式有三个地...

  • 前言从2020年3月份开始,计划写一系列文档--《小白从零开始学编程》,记录自己从0开始学习的一些东西。第一个系列:python,计划从安装、环境搭建、基本语法、到利用Django和Flask两个当前最热的web框架完成一个小的项目第二个系列:可能会选择Go语言,也可能会选择Vue.js。具体情况待定,拭目以待吧。。。基本概念表达式表...

  • 1.1函数1.1.1什么是函数函数就是程序实现模块化的基本单元,一般实现某一功能的集合。函数名:就相当于是程序代码集合的名称参数:就是函数运算时需要参与运算的值被称作为参数函数体:程序的某个功能,进行一系列的逻辑运算return 返回值:函数的返回值能表示函数的运行结果或运行状态。1.1.2函数的作用函数是组织好的,可重复使用的,用来...

  • 原标题:基于Python建立深度神经网络!你学会了嘛?图1 神经网络构造的例子(符号说明:上标[l]表示与第l层;上标(i)表示第i个例子;下标i表示矢量第i项)单层神经网络图2 单层神经网络示例神经元模型是先计算一个线性函数(z=Wx+b),接着再计算一个激活函数。一般来说,神经元模型的输出值是a=g(Wx+b),其中g是激活函数(...

  • 在学习MySQL的时候你会发现,它有非常多的函数,在学习的时候没有侧重。小编刚开始学习的时候也会有这个感觉。不过,经过一段时间的学习之后,小编发现尽管函数有很多,但是常用的却只有那几个。今天小编就把常用的函数汇总一下,为大家能够能好的学习MySQL中的函数。MySQL常使用的函数大概有四类。时间函数、数学函数、字符函数、控制函数。让我...

  • 在我们面试过程中,面试官经常会问到这么一个问题,那就是从在浏览器地址栏中输入URL到页面显示,浏览器到底发生了什么?这个问题看起来是老生常谈,但是这个问题回答的好坏,确实可以很好的反映出面试者知识的广度和深度。本文从浏览器角度来告诉你,URL后输入后按回车,浏览器内部究竟发生了什么,读完本文后,你将了解到:浏览器内有哪些进程,这些...

  • 进程与线程进程(process)就是任务,是计算机系统进行资源分配和调度的基本单位[1]。比如,打开一个word文件就是启动了一个word进程。线程(thread)是进程内的子任务。比如word中可以进行编辑、拼写检查和打印等子任务。我们目前的操作系统都是多任务的操作系统,多任务的实现方式[2]:多进程多线程多进程 + 多线程多进程:...

  • 运行cmd netstat -aon|findstr 80 然后 taskkill -f -pid 32428(这个就是pid进程编号) 回车   进程死翘翘了~ 去愉快玩耍吧~哦对了 别忘记一健三联关注我哟~...

  • 首要解决的问题是如何唯一标识一个进程,否则通信无从谈起!在本地可以通过进程PID来唯一标识一个进程,但是在网络中这是行不通的。其实TCP/IP协议族已经帮我们解决了这个问题,网络层的“ip地址”可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用程序(进程)。这样利用三元组(ip地址,协议,端口)就可以标识网...

  • 1.      SIGTERM “kill pid” 会发送SIGTERM到进程pid. This is the termination signal sent by killcommand by default. 2.      SIGINT 在终端中敲入interrupt key(DELETE或ctrl+c)会产生SIG...

  • 英语的重要性,毋庸置疑!尤其对广大职场人士,掌握英语意味着就多了一项竞争的技能。那,对于我们成人来说,时间是最宝贵的。如何短时间内在英语方面有所突破,这是我们最关心的事情。英语学习,到底有没有捷径可以走,是否可以速成?周老师在这里明确告诉大家,英语学习,没有绝对的捷径走,但是可以少走弯路。十多年的教学经验告诉我们,成功的学习方法可以借...

  • 展开全部 其实IDLE提供了一个显32313133353236313431303231363533e78988e69d8331333365663438示所有行和所有字符的功能。 我们打开IDLE shell或者IDLE编辑器,可以看到左下角有个Ln和Col,事实上,Ln是当前光标所在行,Col是当前光标所在列。 我们如果想得到文件代码...

  • 前言[1]从 Main 方法说起[2]走进 Tomcat 内部[3]总结[4]《Java 2019 超神之路》《Dubbo 实现原理与源码解析 —— 精品合集》《Spring 实现原理与源码解析 —— 精品合集》《MyBatis 实现原理与源码解析 —— 精品合集》《Spring MVC 实现原理与源码解析 —— 精品合集》《Spri...

  • 【本文摘要】【注】本文所述内容为学习Yjango《学习观》相关视频之后的总结,观点归Yjango所有,本文仅作为学习之用。阅读本节,会让你对英语这类运动类知识的学习豁然开朗,你会知道英语学习方面,我们的症结所在。学习英语这类运动类知识,需要把握四个原则第一,不要用主动意识。第二,关注于端对端第三,输入输出符合实际情况第四,通过多个例子...

  • 点云PCL免费知识星球,点云论文速读。文章:RGB-D SLAM with Structural Regularities作者:Yanyan Li , Raza Yunus , Nikolas Brasch , Nassir Navab and Federico Tombari编译:点云PCL代码:https://github.co...