目录
1. int execl( const char *path,const char *arg, ...);
2.int execlp(const char *file,const char *arg, ...);
3、int”execle(const,char,*path,, const. char.*arg, ,... ,char。*const. envp[]);
4、int execv(const char *path, char *const argv[]);
-
1为什么要进程替换
- 因为父进程创建出来的子进程和父进程拥有相同的代码段,所以,子进程看到的代码和父进程是一样的。当我们想要让子进程执行不同的程序时候,就需要让子进程调用进程程序替换的接口,从而让子进程执行不一样的代码
- 举个实例:像牛客网这些刷题网站他在接收你写的程序时就会创建一个子进程,让子进程去执行你的代码,这样即使你的代码写的有问题那也是子进程崩掉了。
-
2原理
- 替换进程的代码段和数据段,更新堆栈。
-
3 exec函数簇
-
1. int execl( const char *path,const char *arg, ...);
- 参数:
- path:带路径的可执行程序(需要路径)
- arg:传递给可执行的程序的命令行参数,第一个参数,需要可执行程序本身,
- 如果需要传递多个参数,则用“,”进行间隔,末尾以NULL结尾
- 返回值:
- 这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。如果调用出错则返回-1
- 应用:
-
如果我们的程序替换成功就不会执行下面的代码了直接执行pwd程序。
-
我们让代码跑起来
-
那么假如要是替换失败就会执行下面的程序。
-
-
2.int execlp(const char *file,const char *arg, ...);
- 参数:
- file:可执行程序,可以不用带有路径,也可以带有路径,这是因为execpl这个函数回去搜索PATH这个环境变量,看看要替换的程序是否在PATH环境变量中
- arg:传递给可执行的程序的命令行参数,第一个参数,需要可执行程序本身,
- 如果需要传递多个参数,则用”,"进行间隔,末尾以NULL结尾
- 返回值:
- 这些函数如果调用成功则加载新的程序从启动代码开始执行,如果调用出错则返回-1
- 验证:我们第一个参数直接不带路径传递参数
- 代码执行起来我们发现程序替换成功
- 结论:
- 函数名当中带有"L" :传递给可执行程序的参数是以可变参数列表的方式进行传递。第一个参数, 需要可执行程序本身,如果需要传递多个参数,则用“,"进行间隔末尾以NULL结尾函数名当中带有“p" :可以使用环境变量PATH,无需写全路径。换句话说,函数会搜索可执行程序PATH,找到可执行程序。 所以不用写路径。
-
3、int”execle(const,char,*path,, const. char.*arg, ,... ,char。*const. envp[]);
- 参数:
- path:带路径的可执行程序(需要路径)
- arg:
- 传递给可执行的程序的命令行参数,第一 个参数,需要 可执行程序本身,
- 如果需要传递多个参数,则用“, "进行间隔,末尾 以NULL结尾
- envp:
- 程序猿传递环境变量,换句话说, 程序 员调用该函数的时候,需要 自己组织环境变量传递给函数。
- 返回值:
- 这些函数如果调用成功则加载新的程序从启动代码开始执行,如果调用出错则返回-1
- 应用:
- 我们这里不给他传环境变量传一个NULL
- 我们发现也可以执行成功
- 我们接下来试着给它传一个环境变量
- 首先我们先写一个获取PATH环境变量的程序
- 将他编译成功,然后我们在execle函数中传入路径,再传入环境变量。
- 我们可以发现传入环境变量后函数替换成功打印处环境变量PATH的值
- 那当我们这里不传如环境变量时
- 我们发现也可以替换成功但是就是不会获取到环境变量的值
- (小知识)_LINE_:打印这句话所在的行号:注意这里是两个下划线__
- 函数名当中带有"e",需要程序猿传递环境变量,换句话说,程序员调用该函数的时候,需要自己组织环境变量传递给函数。
-
4、int execv(const char *path, char *const argv[]);
- 参数:
- path: 带路径的可执行程序(需要路径)
- argv :
- 传递给可执行的程序的命令行参数,以指针数组的方式进行传递。
- 第一个参数,需要可执行程序本身,多个参数就都放到数组当中
- 多个参数要放到数组中,末尾以NULL结尾
- 返回值:
- 这些函数如果调用成功则加载新的程序从启动代码开始执行。
- 如果调用出错则返回-1
- 测试:
- 我们可以发现这里只需要将上面输入参数列表的命令行参数以指针数组方式传入函数就可以了。
- 我们发现程序替换成功
- 总结:如果我们的函数中带有v的是以字符指针数组的方式传递命令行参数。字符指针数组需要程序员自己定义。
- 参数:
- 5、int. execvp(const char:*file, , char ' *const argv[]);
- 参数:
- file:可执行程序, 可以不用带有路径,也可以带 有路径
- argv,:传递给可执行的程序的命令行参数,以指针数组的方 式进行传递。
- 第一个参数,需要 可执行程序本身,多个参数就都放到数组当中末尾以NULL结尾
- 返回值:
- 这些函数如果调用成功则加载新的程序从启动代码开始执行,如果调用出错则返回-1
- 应用:因为函数中带有p所以我们直接不给他穿路径,因为他会搜索环境变量PATH。
- 我们发现也可以执行成功
- 参数:
- 6、int execve(const char *path, char *const argv[], char *const envp[]);
- 参数:
- path:带路径的可执行程序(需要路径)
- argv ;传递给可执行的程序的命令行参数,以指针数组的方式进行传递。
- 第一个参数, 需要可执行程序本身,多个参数就都放到数组当中末尾以NULL结尾
- envp ;程序猿传递环境变量,换句话说,程序员调用该函数的时候,需要自己组织环境变量传递给函数。
- path:带路径的可执行程序(需要路径)
- 返回值:
- 这些函数如果调用成功则加载新的程序从启动代码开始执行,
- 如果调用出错则返回-1
- 测试:
- 我们还是以上面写的my_getenv函数来演示,传入my_getenv函数的地址,并用指针数组组织命令行参数。将环境变量传入
- 可以看到程序成功替换
- 参数:
-
4、创建子进程父进程进行进程等待,然后子进程执行自己代码:
-
当前在父进程是死等子进程的,在子进程不退出之前,父进程是什么也不干的。我们可以看到进程替换成功
-
看到这里如果觉得对你有用不如点个赞吧!!!
-