Linux:进程步调更换

[复制链接]
发表于 2025-10-14 18:54:09 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
目次
前言 
一 进程步调更换的概念
二 进程步调更换的原理
三 为什么须要举行进程步调更换
四 怎样举行进程步调更换 
1. 进程更换函数
➊ execl()函数
 ➋execv()函数
➌execlp()函数 
 ➍execle()函数
➎execve()* 



前言 

一样寻常环境下,对应的语言写的步调只能调用对应的语言的接口,对于别的范例的语言的接口,如C++就不能 调用java大概python的接口,那假如我们想要调用别人的接口怎么办?以是进程步调更换就能很好的办理这个标题,如许我们就可以利用现成其他语言接口的步调而不消耗力地去再实现一个,很洪流平上能镌汰我们的编程资本。

一 进程步调更换的概念

进程步调更换按照字面意思明确就是利用一个新的步调来更换掉原来的步调,此时进程将实验新步调的代码,而不再实验原有步调的代码。一样寻常环境下,我们都是在父进程中fork一个子进程出来,让子进程去实验新步调的代码。

二 进程步调更换的原理

   用fork创建子进程后实验的是和父进程类似的步调(但有大概实验差别的代码分支),子进程通常要调用一种exec函数 以实验另一个步调。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新步调更换,重新步调的启动开始实验。调用exec并不创建新进程,以是调用exec前后该进程的id并未改变。
  

   假设一开始父子进程都实验的是可实验步调A,假如反面想要实验B步调,那么此时就须要举行进程步调更换,发生更换的时间,操纵体系会调用体系调用接口,起首操纵体系会将父进程的代码和数据拷贝一份,然后将B步调加载到内存中,重新创建子进程的页表,更新子进程的页表中的映射关系,但是这里修改的只是子进程页表中的物理地点那一栏,此时的父子进程的假造地点那一栏还是一样的,只不外操纵体系修改了假造地点和物理地点之间的映射关系,从而实现了父子进程的代码分离。此时父子进程是互不干扰的。
  进程更换后: 

以是进程步调更换就是想让子进程去实验其他磁盘的文件,其本质还是将指定步调的代码和数据加载到指定位置(即覆盖掉原来的本身的代码和数据。) 

三 为什么须要举行进程步调更换

   我们在Linux下举行体系编程的时间,我们在创建子进程后,一样寻常是让它实验父进程的代码片断大概让子进程单独去实验磁盘中的其他步调,其他步调大概操持:C/C++、java等差别语言的步调。想让子进程处理处罚反面的事的时间就须要举行进程步调更换。
  
四 怎样举行进程步调更换 

进程步调更换是由操纵体系通过调用体系接口来实现的,但是我们须要提前明确一个点,就是利用这些调用接口的注意事项,我们在更换步调的时间,肯定须要知道这个步调在那边吧,在找到这个步调之后,我们还须要知道怎样去实验这个步调,就像shell下令行中输入下令一样,在下令反面大概还带有许多选项。
1. 进程更换函数

操纵体系中有着六种以exec开头的函数,统称exec函数



  • 这些函数假如调用乐成则加载新的步调从启动代码开始实验。假如调用堕落则返回-1;以是说exec()函数只有堕落的返回值而没有乐成的返回值。 
  • 可以看到这些函数名字都有着许多的共同点:同样都是exec开始的,反面跟差别的字母以体现差别的功能。
  • 再看他们的参数,我们都可以大概猜出来一二,比如path体现更换的步调路径,arg我们在环境变量一篇中见过,体现怎样实验该下令,就像shell下令行里下令后跟的选项一样,如 ls -a的“-a”。“...”体现的是可变参数,file体现的是更换步调的文件名,envp体现的是环境变量
  • l(list):体现参数接纳列表,
  • v(vector):体现参数利用数组
  • p(path):自动搜索环境变量PATH
  • e(env):体现本身维护环境变量
➊ execl()函数

我们fork()出一个子进程让它去实验shell下令中的ls下令,而且带上选项参数。我们利用execl函数,传的参数是ls下令的路径和可实验下令及选项参数,而且要以NULL末了(告诉函数传参竣事)

运行结果 

   ✍为什么printf("proces  running done") 没有打印呢
   printf("proces  running done")是在execl之后,execl实验完毕的时间,代码已经完全覆盖,开始实验新的代码的步调,以是printf就无法实验了。
  前面也说了这些函数假如调用乐成则加载新的步调从启动代码开始实验。假如调用堕落则返回-1;以是说exec()函数只有堕落的返回值而没有乐成的返回值。 那为什么调用乐成了没有返回值呢,由于调用乐成之后,步调更换之后,不再实验后续代码,以是更换乐成之后返回值已经没意义了。
   ➋execv()函数

该函数和execl相比力就差在参数存放的方式,后者是以列表方式存放,而该函数是以数组方式存放(vector)


➌execlp()函数 

该函数和execl()相比就是多了个P,这里的P指的就是PATH,指的是体系直接到环境变量PATH中去探求对应的步调,以是在第一个参数中我们并不须要传路径。
​
​
   ✉上述操纵,我们都是实验体系下令,假如我们想更换本身写的步调,该怎样做。 
  
​
​ 
​ makefile文件(多文件下) 
​
运行结果 
​
   
步调更换:可以利用步调更换,调用任何后端语言对于的恣意可实验 

   ➍execle()函数

   这个函数与前几个函数相比多了一个e,那么这个e是什么呢?e体现的是环境变量,这个接口的作用是可以给想要实验的步调传入本身界说的环境变量。第三个参数可以覆盖式的将想要传的环境变量传给想要实验的步调,一样寻常两种环境,第一种就是直接传入自界说的环境变量,第二种就是通过environ,并将自界说的环境导出为体系的环境变量
  
​
​
 ​


  • 值得注意的是,execle()函数在传入时,这个环境是覆盖式地传入,并不是新增式地传入,这也就是为什么我们打印出来地只有本身界说的环境变量,由于它们把之前的环境变量都覆盖掉了。

 
怎样不覆盖式地添加新的环境变量传给子进程呢? 


➎execve()* 

  1. int execve(const char *filename, char *const argv[], char *const envp[]);
复制代码
上面的函数本质上都调用了该函数,以是是该函数的封装,是体系真正的调用接口。 

回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表