传统艺能😎
小编是双非本科大二菜鸟不赘述,欢迎米娜桑来指点江山哦
1319365055
🎉🎉非科班转码社区诚邀您入驻🎉🎉
小伙伴们,满怀希望,所向披靡,打码一路向北
一个人的单打独斗不如一群人的砥砺前行
这是和梦想合伙人组建的社区,诚邀各位有志之士的加入!!
社区用户好文均加精(“标兵”文章字数2000+加精,“达人”文章字数1500+加精)
直达: 社区链接点我
概念🤔
你是否遇到过这样一个场景,**在一个多人项目中,有人用 Java 实现部分功能,有人用 C++ 实现部分功能,有人用 PHP,go,Python……**那该如何将这些不同的逻辑语言统一进来呢?
当我们 fork() 生成子进程后,子进程的代码与数据可以来自其他可执行程序。把磁盘上其他程序的数据以覆盖的形式给子进程。这样子进程就可以执行全新的程序了,这种现象称为 程序替换 \color{red} {程序替换} 程序替换
细则🤔
首先需要知道进程替换是有原则的:
-
进程替换不会创建新进程,因为他只是将该进程数据替换为指定的可执行程序。而进程 PCB 没有改变,所以不是新的进程,进程替换后不会改变 pid
-
替换成功后,替换函数后的代码不会执行,因为进程替换是覆盖式的,替换成功后进程原来的代码就消失了,同理替换失败会执行替换函数后的代码
-
进程替换函数在进程替换成功后不返回,函数的返回值只会表示替换失败;进程替换成功后,退出码为替换后进程的退出码
原理🤔
替换是用的是替换函数: e x e c 函数 \color{red} {exec 函数} exec函数
该函数类型使用头文件:<unistd.h>
函数原型:int execl(const char *path,const char *arg,…)
path:可执行程序的路径
arg:如何执行可执行程序
… :可变参数,是给执行程序携带的参数,在参数末尾加 NULL 表示参数结束
返回值:替换失败返回-1,替换成功不返回
当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,并从新程序的启动例程开始执行,本质上和虚拟内存和写时拷贝机制有点类似,通过在页表上进行映射操作进行替换:
那么子进程程序替换后,会对父进程产生印象吗?
毫无疑问,子进程被创建时是与父进程共享代码和数据,但当程序替换时,也就意味着需要进行写入操作,这时便需要将父子进程共享的代码和数据进行写时拷贝,此后父子进程的代码和数据也就分离了,因此进行程序替换后不会影响父进程的代码和数据!
exec 函数🤔
进程替换有六种替换函数,他们是以 exec 开头的函数,统称为 exec 函数:
execl😋
int execl(const char *path, const char *arg, ...);
第一个参数是要执行程序的路径,第二个参数是可变参数列表,代表我们需要以 list 的形式处理各种操作,内容是各个指令选项,并以NULL结尾
以 ls 命令为例:
execl("/usr/bin/ls", "ls", "-a", "-i", "-l", NULL);
execlp😋
int execlp(const char *file, const char *arg, ...);
第一个参数是要执行程序的名字,第二个参数是可变参数列表,代表我们需要以 list 的形式处理各种操作,内容是各个指令选项,并以NULL结尾
同样以 ls 命令为例:
execlp("ls", "ls", "-a", "-i", "-l", NULL);
execle😋
int execle(const char *