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

代理注册公司代理费多少钱实时seo排名点击软件

代理注册公司代理费多少钱,实时seo排名点击软件,设计工作室名字创意好听,最近时政新闻标题:[Linux] Linux 进程程序替换 个人主页水墨不写bug (图片来源于网络) 目录 O、前言 一、进程程序替换的直观现象(什么是进程程序替换?) 二、进程程序替换的原理 三、进程程序替换的函数&#xff08…

标题:[Linux] Linux 进程程序替换

个人主页@水墨不写bug

(图片来源于网络)

目录

O、前言

一、进程程序替换的直观现象(什么是进程程序替换?)

二、进程程序替换的原理

三、进程程序替换的函数(怎么使用进程程序替换?)

1.execl

2.execlp

3.execle

1.execv

2.execvp

3.execve

四、进程程序替换的实际应用场景(程序替换的意义?)

进程替换的常见场景:


 正文开始:

O、前言

        在之前,我们已经学习了什么是进程的创建,退出,等待,以及有关进程地址空间的问题。接下来的进程程序替换依然是属于进程控制的范畴,但是在实际应用中,是非常重要的一种技术。

        本文不直接像书本上一样,一开始就说一大堆概念,让人摸不清头脑,而是现观察进程程序替换的现象,然后再从现象中在进一步了解进程程序替换。

一、进程程序替换的直观现象(什么是进程程序替换?)

         进程程序替换有一些专门(对口)的函数,我们可以通过man手册查到其中的一个函数:

        接下来我们直接看一段代码,用一用这个函数:

#include<stdio.h>
#include<unistd.h>int main()
{printf("process begin...\n");execl("/usr/bin/ls","ls","-a","-l",NULL);printf("process end...\n");return 0;
}

         两个打印语句分别标识进程开始与结束,话不多说,直接开始运行,结果如下:

        我们惊奇的发现,执行的现象与使用ls的现象差不多!

        通过进一步观察,可以发现:

        1)在调用execl函数之前的代码(打印process begin 的语句)执行了;

        2)调用execl函数就好像使用了 “ls” 命令;

        3)调用execl函数之后的代码没有被执行。

        为什么会发生这样的情况呢?别急,这就需要深入了解调用execl函数这一动作背后到底发生了什么——于是,我们需要谈一谈进程替换的原理。

二、进程程序替换的原理

        我们知道,我们写好并编译好的文件是一个 独立的 可执行程序:

        包括我们自己写的mytest,或者是系统上已经装好的ls等指令,都是一个独立的可执行程序。  

         execl 这类函数的功能就是,把一个新的独立的可执行程序覆盖式的加载到原来的运行起来的进程中,从而实现程序替换。

        一个进程,包括内核数据结构 + 代码和数据;这里的程序替换,替换的不仅仅是数据,还要替换代码!这也就意味着原来的代码和数据就被覆盖了,于是进程会从执行execl函数这一行开始,直接执行新加载的代码和数据。原来的数据自然就丢失了:这也就解释了 执行 execl 就像执行力 ls指令 ,在最后执行结束之后并没有打印 “process end” 的原因:

        1)执行execl之后,ls的代码和数据被加载的内存中,覆盖替换了原来的代码和数据;

        2)原来的 打印   “process end” 的代码由于被覆盖而丢失,所以没有执行;

        3)最终的返回值是ls指令的返回值,而不再是原来被覆盖的进程的返回值。


三、进程程序替换的函数(怎么使用进程程序替换?)

        我们可以通过进程程序替换的函数名称来略知一二,但是在那样通过函数名称来快速记忆之前,我们还是需要先一个一个了解进程程序替换的函数们:

list(初始化列类型):

1.execl

         就像我们之前演示的那样,其实就是execl函数使用方法,接下来需要对这个函数的传参细节做一些深入理解:

参数列表:

        *pathname: 需要替换的可执行程序的位置,需要指明具体的位置,既可以使用绝对路径,也可以使用相对路径。

        (比如想要替换ls命令,ls命令本质是一个可执行程序,位于/usr/bin/ls,于是我们第一个参数需要这样传递:“/usr/bin/ls”)

        *arg: 需要替换的可执行程序的名称

        (需要替换的ls命令的名称就是ls,于是需要传递:“ls”)

         ... : 参数列表

        (类似于printf的参数列表不限制打印的参数的个数一样,我们在命令行上想要使用不同的命令,传递的参数的个数是不同的,于是通过参数列表,我们可以传递不同的参数个数,来达到正确执行不同指令的目的)

        比如下面的这一个实例就很好的体现了上述的规则:

实例一:

 makefile:        

        当我们想要一次生成多个目标文件,那么可以定义一个伪目标:all 

        在伪目标后面 + “ : ”+ “ 需要的依赖文件名称 ” 

        在下文表明生成依赖文件的依赖方法即可:

.PHONY:all
all:mytest mmtestmmtest:mytest.ccg++ -o $@ $^
mytest:pra_exec.cgcc -o $@ $^.PHONY:clean
clean:rm -r mytest mmtest

pra_exec.c:

#include<stdio.h>
#include<unistd.h>int main()
{printf("process begin...\n");execl("/usr/bin/ls","ls","-a","-l",NULL);printf("process end...\n");return 0;
}

mytest.cc

#include<iostream>
#include<unistd.h>
using namespace std;int main()
{cout<<"C++进程开始运行"<<endl;execl("./mytest","./mytest",NULL);cout<<"C++进程结束运行"<<endl;return 0;
}

        由于我们已经编写了makefile,所以只需要make,就可以生成两个可执行程序。

        运行结果:

        在进程运行的过程中,我们发现进行了两次进程程序替换:

        ./mmytest (C++程序) ---> ./mytest(C程序) ---> /usr/bin/ls (系统命令C程序)

我们可以通过观察打印信息来观察。

        到这里我们可以得出结论:

                execl可以替换任何语言的可执行程序。(包括java,python,shell脚本语言等),唯一不同的是通过execl调用的时候传递的参数不同。

接下来的介绍只给出具体函数的使用实例,不再重复介绍同样性质的参数。 

2.execlp

#include <unistd.h>
int main()
{// 带p的,可以使用环境变量PATH,无需写全路径execlp("ps", "ps", "-ef", NULL);exit(0);
}

3.execle

#include <unistd.h>
int main()
{char *const envp[] = {"PATH=/bin:/usr/bin", "TERM=console", NULL};// 带e的,需要自己组装环境变量execle("ps", "ps", "-ef", NULL, envp);exit(0);
}

vector(数组类型):

1.execv

#include <unistd.h>
int main()
{char *const argv[] = {"ps", "-ef", NULL};//带v的需要传入数组形式的参数列表 execv("/bin/ps", argv);exit(0);
}

2.execvp

#include <unistd.h>
int main()
{char *const argv[] = {"ps", "-ef", NULL};// 带p的,可以使用环境变量PATH,无需写全路径execvp("ps", argv);exit(0);
}

3.execve

#include <unistd.h>
int main()
{char *const argv[] = {"ps", "-ef", NULL};char *const envp[] = {"PATH=/bin:/usr/bin", "TERM=console", NULL};// 带e的,需要自己组装环境变量execve("/bin/ps", argv, envp);exit(0);
}

函数解释

        这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。

        如果调用出错则返回-1

        所以exec函数只有出错的返回值而没有成功的返回值。

命名理解

这些函数原型看起来很容易混,但只要掌握了规律就很好记。

l(list) : 表示参数采用列表

v(vector) : 参数用数组

p(path) : 有p自动搜索环境变量PATH

e(env) : 表示自己维护环境变量

 exec*函数簇函数之间的关系:

        本质上,这些exec*函数都是对execve函数的封装,为什么?

        因为execve是一个系统调用函数!!本质上底层调用的都是相同的形式调用的execve,只不过是上层的封装转换的参数传递的方式。


四、进程程序替换的实际应用场景(程序替换的意义?)

        在我们的项目中,我们的父进程一直是运行的,不能说父进程执行了想要执行ls命令,在执行了之后自己却退出了。所以,我们在一般情况下,一定不能让父进程发生程序替换,不然父进程的代码和数据被子进程替换之后,代码和数据就丢失了!        

         所以我们需要fork创建子进程,让子进程来代替父进程来执行exec*这一类的函数,让子进程来发生程序替换,让子进程的代码和数据被替换掉,这样父进程就可以保留!

进程替换的常见场景:

        用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。

        当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。

        调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。


完~

未经作者同意禁止转载 

http://www.wooajung.com/news/30213.html

相关文章:

  • 东莞凤岗做网站全国疫情的最新数据
  • 如何进行网站推广关键词简谱
  • 外贸做的亚马逊网站是哪个卡点视频软件下载
  • 品牌网站建设价位事件营销成功案例
  • 广元网站建设电脑培训班在哪里有最近的
  • 韩城做网站东莞网络推广培训
  • 网站难做吗百度关键字搜索排名
  • 网站模板破解版沈阳seo顾问
  • 个人备案放企业网站重庆人力资源和社会保障网官网
  • 门户网站建设经验交流网上学电脑培训中心
  • 广州白云区做网站手机网络优化
  • 个人网站备案做商城谷歌三件套
  • 云南建设厅网站安全员报名入口网易疫情实时最新数据
  • 商洛免费做网站磁力岛
  • 网站建设费分多少期摊销百度认证服务平台
  • 有个爱聊天网站做兼职的靠谱吗厦门百度关键词seo收费
  • 地方电商网站常用的网络推广的方法有哪些
  • 企业网站优化之如何做需求分析网络快速排名优化方法
  • 网站做支付按流量付费app推广注册接单平台
  • 工信部 网站备案查询北京网站优化方法
  • 电子商务网站建设试题答案seo实战培训
  • 网站建设要会什么软件百度百科推广费用
  • 网页制作软件都有哪些长春seo排名扣费
  • 静态网站论文目录百度搜索关键词排名
  • 建设网站用什么软件下载自建站怎么推广
  • wordpress 太卡揭阳百度快照优化排名
  • 西安做网站哪家比较好博客网站注册
  • 企业网站官网制作百度有人工客服吗
  • 怎么自己做导航网站网络优化器免费
  • 17一起做网站株洲网络推广营销方法