【Linux】——进程控制(下)

立山  金牌会员 | 2025-2-12 18:19:28 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 901|帖子 901|积分 2703



 

目录

一、前言
二、进程替换
1.进程替换的概念
2.单进程下的进程替换
 3.进程替换的原理
4. 程序替换函数
①函数解释
②命名明白
三、结语


一、前言

           本文将为大家带来进程控制的末了一部分内容:进程替换,希望大家能够有所收获!!!
  二、进程替换

1.进程替换的概念

           Linux中的进程替换‌是指在一个正在运行的进程中,用一个新的程序替换当进步程的代码和数据,使得进程开始执行新的程序,而不是原来的程序。这种技能通常用于在不创建新进程的情况下,改变进程的运动‌
  2.单进程下的进程替换

           在进程替换的原理讲授之前,先为小伙伴演示下什么是进程替换,常用的进程替换函数共有6个,我们先以execl为例
  1.   1 #include <stdio.h>
  2.   2 #include <unistd.h>
  3.   3 #include <stdlib.h>
  4.   4  
  5.   5  
  6.   6  
  7.   7 int main()
  8.   8 {
  9.   9     printf("before: I am a process , pid: %d, ppid: %d\n",getpid(),getppid());
  10. 10  
  11. 11     //标准写法
  12. 12     execl("/usr/bin/ls","ls","-a","-l",NULL);
  13. 13                                                                                            
  14. 14  
  15. 15     printf("after: I am a process , pid: %d, ppid: %d\n",getpid(),getppid());
  16. 16     return 0;
  17. 17 }
复制代码
代码征象 

           看到结果之后,大概会和大家盼望的会有所不同,就是为啥execl后面的代码没有被进程执行呢,这就和进程替换的原理有关了,且看下面讲授 
   3.进程替换的原理

           用fork创建子进程后执行的是和父进程雷同的程序(但有大概执行不同的代码分支),子进程每每要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,重新程序的启动例程开始执行。调用exec并不创建新进程,以是调用exec前后该进程的id并未改变。
     
  补充:
          征象:程序替换成功之后,exec*后续的代码不会被执行;只有替换失败,才大概执行后续的代码,因此exec*函数,只有失败返回值,没有成功返回值
          小知识:Linux中形成的可执行程序,是有格式的,ELF,可执行程序的表头,而可执行程序的入口地址就在表中,因此程序替换之后才知道从哪里开始执行代码
  

4. 程序替换函数

有六种以exec开头的函数,统称exec函数:
   #include <unistd.h>
  
  int execl(const char *path, const char *arg, ...);
  int execlp(const char *file, const char *arg, ...);
  int execle(const char *path, const char *arg, ...,char *const envp[]);
  
  int execv(const char *path, char *const argv[]);
  int execvp(const char *file, char *const argv[]);
  int execve(const char *path, char *const argv[], char *const envp[]);
  ①函数解释

   ●这些函数假如调用成功则加载新的程序从启动代码开始执行,不再返回
  ●假如调用堕落则返回-1
  ●以是exec函数只有堕落的返回值而没有成功的返回值
  ②命名明白

   ●l(list) : 表示参数接纳列表
  ●v(vector) : 参数用数组
  ●p(path) : 有p自动搜刮情况变量PATH
  ●e(env) : 表示自己维护情况变量
  

 exec调用举例如下:
  1. #include <unistd.h>
  2. int main()
  3. {
  4. char *const argv[] = {"ps", "-ef", NULL};
  5. char *const envp[] = {"PATH=/bin:/usr/bin", "TERM=console", NULL};
  6. execl("/bin/ps", "ps", "-ef", NULL);
  7. // 带p的,可以使用环境变量PATH,无需写全路径
  8. execlp("ps", "ps", "-ef", NULL);
  9. // 带e的,需要自己组装环境变量
  10. execle("ps", "ps", "-ef", NULL, envp);
  11. execv("/bin/ps", argv);
  12. // 带p的,可以使用环境变量PATH,无需写全路径
  13. execvp("ps", argv);
  14. // 带e的,需要自己组装环境变量
  15. execve("/bin/ps", argv, envp);
  16. exit(0);
  17. }
复制代码
事实上,只有execve是真正的系统调用,别的五个函数最终都调用 execve,以是execve在man手册 第2节,别的函数在man手册第3节。这些函数之间的关系如下图所示。
下图exec函数族 一个完整的例子: 

三、结语

             到此为止,本文有关进程替换的讲授就到此结束了,如有不敷之处,欢迎小伙伴们指出呀!
           关注我 _麦麦_分享更多干货:_麦麦_-CSDN博客
        大家的「关注❤️ + 点赞
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

立山

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表