银川建设网站公司,网站搜索引擎优化的基本内容,自建站平台,网站页面设计培训本篇文章会对进程替换进行讲解。希望本篇文章会对你有所帮助 文章目录 一、进程替换概念 二、进程替换函数 2、1 execl 2、2 execlp 2、3 execv 2、3 execle 2、4 execve 三、总结 #x1f64b;♂️ 作者#xff1a;Ggggggtm #x1f64b;♂️ #x1f440; 专栏… 本篇文章会对进程替换进行讲解。希望本篇文章会对你有所帮助 文章目录 一、进程替换概念 二、进程替换函数 2、1 execl 2、2 execlp 2、3 execv 2、3 execle 2、4 execve 三、总结 ♂️ 作者Ggggggtm ♂️ 专栏Linux从入门到精通 标题进程控制 ❣️ 寄语与其忙着诉苦不如低头赶路奋路前行终将遇到一番好风景 ❣️ 一、进程替换概念 我们知道fork() 创建子进程子进程的代码和数据是和父进程共享一份的。当对任意一个进程修改时就会发生写时拷贝。当时我们就想让子进程执行一份全新的代码呢那我们可以使用进程替换。 程序替换就是使用一个接口来实现的。把磁盘上的可执行程序加载到进程的地址空间上。可结合下图理解 进程替换就是把磁盘上的可执行程序加载到了内存中已经在运行的进程中加载上的新程序会与原来的进程的页表构成新的映射关系实际上并没有创建新的进程。 二、进程替换函数
2、1 execl 我们先来看一下execl函数怎么使用如下图 第一个参数是指你所要替换程序的路径。后面的参数是要怎么执行该程序是一个可变参数列表但是最后一个参数必须为空。具体使用如下 #includestdio.h
#includeunistd.h
#includestdlib.h int main()
{ printf(hello linux\n); execl(/usr/bin/ls,ls,-l,NULL); printf(hello linux\n); exit(111); return 0;
} 我们看如下运行结果 确实执行了ls -l 的命令但是并没有往下接着执行打印和退出怎么没有打印呢execl是程序替换调用该函数后会将当前的进程所有代码和数据进行替换。所以一旦调用成功后续的代码将不会在被执行。 exec()系列函数在成功时不会返回只有在发生错误时才会返回-1。这是因为当exec()函数成功地加载新的可执行程序后它会在当前进程上下文中完全替换掉当前进程的映像包括代码、数据、堆栈等。这使得原先的进程状态被新的可执行程序取代所以在成功加载新程序后旧程序不再存在也就无法进行返回操作了。 2、2 execlp execlp函数对比execl函数就是所要替换的程序可以自己不带路径。execlp中的 p 指的意思是环境变量PATH可以默认去找所要替换的程序路径。代码如下 #includestdio.h #includeunistd.h #includestdlib.h int main() { printf(hello linux\n); //execl(/usr/bin/ls,ls,-l,NULL); execlp(ls,ls,-l,-a,NULL); printf(hello linux\n); exit(111); return 0; } 运行结果如下 2、3 execv 我们再来看一下execv函数的使用。如下图 其实对比execl函数不难发现l 表示list的意思也就是参数列表一个一个列出来。execv函数中的 v 表示vector参数列表是一个数组。我们可看如下代码 #includestdio.h #includeunistd.h #includestdlib.h char* const _argv[]{ls,-l,-a,NULL}; int main() { printf(hello linux\n); //execl(/usr/bin/ls,ls,-l,NULL); execv(/usr/bin/ls,_argv); printf(hello linux\n); exit(111); return 0; } 运行结果如下 2、3 execle 我们这里就不再解释execvp了对比上述讲到很容易理解。直接看execle函数。我们先看execle函数怎么使用 其实我们也不难发现对比execl函数参数列表最后多出来一个指针数组。这个指针数组就是维护的环境变量。为了更好的演示该函数我们先写一下一个我们自己生成的可执行程序去调用我们另一个自己生成的可执行程序。代码如下 //“————————————————myexec.c————————————————————”#includestdio.h #includeunistd.h #includestdlib.h const char* myflie/home/gtm/primer/test/test_7_23/mycmd; int main(int argc,char* argv[],char* env[]) { printf(hello linux\n); //execl(/usr/bin/ls,ls,-l,NULL); //execlp(ls,ls,-l,-a,NULL); execle(myflie,mycmd,-a,NULL,env); //execv(/usr/bin/ls,_argv); return 0; } //“————————————————mycmd.c————————————————————”
#include stdio.h
#include string.h
#include stdlib.h// ./mycmd -a/-b/-c...
int main(int argc, char *argv[])
{if(argc ! 2){printf(can not execute\n);exit(1);}//MY_105_VAL: 目前并不存在printf(获取环境变量: hello: %s\n, getenv(hello));if(strcmp(argv[1], -a) 0) { printf(hello a!\n); } else if(strcmp(argv[1], -b) 0) { printf(hello b!\n); } else{ printf(default!\n); } return 0;
} 上述代码是在不同的源文件上述代码中有所标述。我们想要的就是用myexec去调用mycmd。我们在mycmd中想要获取环境变量 hello 的值但是哦我们并没有设置。所以环境变量hello的值为null。我们看运行结果 但是我们要在myexec中设置了hello环境变量 #includestdio.h #includeunistd.h #includestdlib.h const char* myflie/home/gtm/primer/test/test_7_23/mycmd; int main(int argc,char* argv[],char* env[]) { printf(hello linux\n); //execl(/usr/bin/ls,ls,-l,NULL); //execlp(ls,ls,-l,-a,NULL); const char* _env[]{hello20230724,NULL}; execle(myflie,mycmd,-a,NULL,_env); //execv(/usr/bin/ls,_argv); return 0; } 我们再来看运行结果 当然环境变量hello就可以获取相应的值。 2、4 execve execve函数是属于系统调用函数。我们上述讲到的如下图 都是语言级别的函数底层封装的都是execve函数。事实上,只有execve是真正的系统调用,其它五个函数最终都调用 execve。为什么还要封装呢直接使用execve多好啊。原因是封装后我们也可以很直接的感受到应用的场景变多了。其次是用起来见名知其意。 三、总结 在C中exec()系列函数提供了一种在程序中执行外部命令或可执行文件的方法。这些函数包括execvp()、execv()、execvpe()、execlp()、execl()、execle()和execve()。 execvp()函数 原型int execvp(const char *file, char *const argv[]);功能用于在指定的文件路径中搜索可执行文件并用指定的参数列表运行该文件。优点可以直接使用文件名作为参数而无需提供文件路径。返回值如果函数执行成功则不会返回任何值如果函数执行失败则会返回-1。 execv()函数 原型int execv(const char *path, char *const argv[]);功能在指定的文件路径中搜索可执行文件并用指定的参数列表运行该文件。优点需要提供文件路径因此可以明确指定要执行的文件的位置。返回值如果函数执行成功则不会返回任何值如果函数执行失败则会返回-1。 execvpe()函数 原型int execvpe(const char *file, char *const argv[], char *const envp[]);功能在指定的文件路径和环境变量中搜索可执行文件并用指定的参数列表运行该文件。优点除了搜索文件路径外还可以指定环境变量。返回值如果函数执行成功则不会返回任何值如果函数执行失败则会返回-1。 execlp()函数 原型int execlp(const char *file, const char *arg, ...);功能在系统的环境变量所指定的路径中搜索可执行文件并用指定的参数列表运行该文件。优点可以直接使用文件名和参数作为参数而无需提供文件路径。返回值如果函数执行成功则不会返回任何值如果函数执行失败则会返回-1。 execl()函数 原型int execl(const char *path, const char *arg, ...);功能在指定的文件路径中搜索可执行文件并用指定的参数列表运行该文件。优点需要提供文件路径和参数因此可以明确指定要执行的文件的位置和所需的参数。返回值如果函数执行成功则不会返回任何值如果函数执行失败则会返回-1。 execle()函数 原型int execle(const char *path, const char *arg, ..., char *const envp[]);功能在指定的文件路径和环境变量中搜索可执行文件并用指定的参数列表运行该文件。优点除了搜索文件路径外还可以指定环境变量。返回值如果函数执行成功则不会返回任何值如果函数执行失败则会返回-1。 execve()函数 原型int execve(const char *filename, char *const argv[], char *const envp[]);功能在指定的文件路径和环境变量中搜索可执行文件并用指定的参数列表运行该文件。优点需要提供文件路径和参数以及环境变量因此可以明确指定要执行的文件的位置、所需的参数和运行环境。返回值如果函数执行成功则不会返回任何值如果函数执行失败则会返回-1。 exec()系列函数允许程序在运行时调用其他可执行文件以实现更复杂的功能。这些函数提供了不同的方式来指定可执行文件的路径、传递参数和设置环境变量根据具体的需求可以选择合适的函数来使用。请注意exec()函数族在执行成功后会将当前进程替换为新的进程因此之后的代码不会被执行到。