• Linux进程程序替换


    目录

    一、引入

    二、程序替换的原理

    三、替换函数

    (一)execl

    (二)execv

    (三)execle

    四、环境变量


    一、引入

    • 我们所创建的所有子进程,执行的代码,都是父进程的一部分。如果想让子进程执行新的程序呢?执行全新的代码和访问全新的数据不再和父进程有关系-------那么就需要进程替换

    二、程序替换的原理

    程序替换(也称为程序加载或程序执行)是指将一个程序从磁盘(或其他存储介质)中读取到内存中,然后用它来替换当前正在运行的进程的代码和数据。 

    三、替换函数

    • 其实有六种以exec开头的函数,统称exec函数
    man excel //命令查看
    1. #include `
    2. int execl(const char *path, const char *arg, ...);
    3. int execlp(const char *file, const char *arg, ...);
    4. int execle(const char *path, const char *arg, ...,char *const envp[]);
    5. int execv(const char *path, char *const argv[]);
    6. int execvp(const char *file, char *const argv[]);
    • 这些函数如果调用成功加载新的程序从启动代码开始执行,不再返回。
    • 如果调用出错则返回-1
    • 所以exec函数只有出错的返回值而没有成功的返回值
    • l(list) : 表示参数采用列表
    • v(vector) : 参数用数组
    • p(path) : 有p自动搜索环境变量PATH
    • e(env) : 表示自己维护环境变量
    1. man execl
    2. man execve

     

    (一)execl

    int execl(const char *path, const char *arg, ...);
    • path表示要执行的程序是谁,在哪?,程序本质也是一个文件(需要先找到程序的路径+文件名)
    • arg表示如何执行的问题?命令行怎么写,就将参数怎么传
    • ...表示可变参数列表
    1. #include
    2. #include//execl的头文件
    3. int main()
    4. {
    5. pid_t id = fork();
    6. if(id == 0)
    7. {
    8. printf("pid: %d, exec command begin\n",getpid());
    9. sleep(2);
    10. execl("/usr/bin/ls","ls","-a","-l","-n",NULL); //最后必须以NULL结尾
    11. printf("pid: %d, exec command end\n",getpid());
    12. }
    13. else{
    14. //父进程
    15. pid_t rid = waitpid(-1, NULL, 0);
    16. if(rid > 0)
    17. {
    18. printf("wait success, rid: %d\n", rid);
    19. }
    20. else if(rid == 0)
    21. {
    22. printf("child is alive, wait again, father do other thing....\n");
    23. }
    24. else{
    25. printf("wait failed!\n");
    26. }
    27. }
    28. return 0;
    29. }

    (二)execv

    int execv(const char *path, char *const argv[]);
    • v(vector):表示以数组的形式传参
    • 第二个参数表示以指针数组的形式传参
    1. #include
    2. #include//exec的头文件
    3. #include//exit的头文件
    4. int main()
    5. {
    6. pid_t id =fork();
    7. if(id == 0)
    8. {
    9. //子进程
    10. char *const argv[]={"ls","-a","-l",NULL};
    11. printf("pid: %d, exec command begin\n",getpid());
    12. execv("/usr/bin/ls",argv);
    13. printf("pid: %d, exec command end\n",getpid());
    14. exit(1);
    15. }
    16. return 0;
    17. }

    (三)execle

    int execle(const char *path, const char *arg, ...,char *const envp[]);
    • envp 参数是一个指向字符串数组的指针,表示新程序的环境变量。这个数组以NULL结尾
    • process.c文件 
    1. #include
    2. #include//exec的头文件
    3. #include//exit的头文件
    4. #include
    5. int main()
    6. {
    7. char* const myenv[]={
    8. "MYVAL1=111111",
    9. "MYVAL2=222222",
    10. "MYVAL3=333333",
    11. NULL
    12. };
    13. pid_t id =fork();
    14. if(id == 0)
    15. {
    16. //子进程
    17. printf("pid: %d, exec command begin\n",getpid());
    18. execle("./test","test","-a","-b",NULL,myenv);
    19. printf("pid: %d, exec command end\n",getpid());
    20. exit(1);
    21. }
    22. return 0;
    23. }
    •  test.cc文件
    1. #include
    2. using namespace std;
    3. int main(int argc, char *argv[],char *env[])
    4. {
    5. cout<
    6. for(int i=0;env[i];i++ )
    7. {
    8. cout<" : "<
    9. }
    10. return 0;
    11. }
    • makefile文件
    1. .PHONY:all
    2. all:test process
    3. test:test.cc
    4. g++ -o $@ $^ -std=c++11
    5. process:process.c
    6. gcc -o $@ $^ -std=c99
    7. .PHONY:clean
    8. clean:
    9. rm -f process test

     

    四、环境变量

    • 当我们进行程序替换的时候,子进程对应的环境变量,是可以直接从父进程来的
    • 环境变量被子进程继承下去是一种默认行为,不受程序替换的影响,为什么?

    通过地址空间可以让子进程继承父进程的环境变量数据

    程序替换,只替换新程序的代码和数据,环境变量不会被替换!!! 

  • 相关阅读:
    Python——函数
    软件设计包括了四个既独立又相互联系的活动
    bootstrapjs开发环境搭建
    Java中的数组,你知道多少细节?
    【MySQL】【牛客-SQL进阶挑战】03 聚合分组查询
    H01-基于深度学习的物体检测-概述
    MobileViT论文记录
    【C语言】扫雷----详解(扩展版)
    Web安全之浅见
    Hive 中常用的函数以及数据类型
  • 原文地址:https://blog.csdn.net/m0_63783532/article/details/134280944