朋友们、伙计们,我们又见面了,本期来给大家解读一下有关Linux程序替换的相关知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成!
C 语 言 专 栏:C语言:从入门到精通
数据结构专栏:数据结构
个 人 主 页 :stackY、
C + + 专 栏 :C++
Linux 专 栏 :Linux
目录
1. 程序替换
我们创建的所有子进程,执行的代码都是父进程代码的一部分!那么如果我们想让子进程执行新的程序呢?执行全新的代码和访问全新的数据,不再和父进程有所瓜葛,那么就需要用到程序替换。
这么多程序替换的函数调用,到底该怎么样用呢?我们直接开始使用:
2. 单进程的程序替换
为了便于理解,我们先从单进程的程序替换开始:
int execl(const char *path, const char *arg, ...);
先来看最简单的程序替换接口,其中里面的三个点表示的意思就是可变参数,使用的方法和我们的printf函数中的可变参数一样;
我们程序要能运行起来,第一步先要找到这个程序,第二部如何运行。
- const char* path表示:新程序的文件路径 + 文件名;
- const char *arg表示:这个程序怎么运行(简单的说我们在命令行怎么输就怎么写,最终以NULL结尾)。
返回值:成功没有返回值,失败返回-1。
我们先来演示一遍:让ls命令替换掉我们写的可执行
#include <stdio.h> #include <unistd.h> int main() { printf("pid: %d, exec command begin\n", getpid()); sleep(3); // 程序替换 execl("/usr/bin/ls", "ls", "-a", "-l", NULL); printf("pid: %d, exec command begin\n", getpid()); return 0; }
通过结果可以发现,我们通过execl成功完成了程序替换,但是代码中的最后一行代码为什么没有打印出来呢?这个到后续再解释!
2.1 单进程程序替换的原理
我们已经完成了单进程的程序替换,那么它的原理是什么呢?
当一个进程运行起来时,OS会为它创建PCB、虚拟地址空间、页表,将它的代码、数据加载到物理内存中,并且然后通过页表建立起虚拟到物理的映射关系;当进行程序替换时,execl就将要替换的程序代码和数据直接在物理内存中替换覆盖掉,此时原来的代码和数据就会被新替换的代码和数据覆盖掉,继续向后执行也就执行的新程序的代码和数据,这个过程中并没有创建新的进程。
3. 多进程的程序替换
见识过单进程的程序替换以及程序替换的原理,接下来替换一下多进程:
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main() { pid_t id = fork(); if(id == 0) { // child printf("pid: %d, exec command begin\n", getpid()); sleep(3); // 程序替换 execl("/usr/bin/ls", "ls", "-a", "-l", NULL); printf("pid: %d, exec command begin\n", getpid()); } // parent pid_t rid = waitpid(id, NULL, 0); if(rid == id) {