【Linux】开始学习进程替换吧!

这篇具有很好参考价值的文章主要介绍了【Linux】开始学习进程替换吧!。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【Linux】开始学习进程替换吧!,一起学Linux吧!,linux,学习,运维,c++,服务器
送给大家一句话:
人生中有些事,你不竭尽所能去做,你永远不知道你自己有多出色。—— 尾田荣一郎《海贼王》

1 前言

通过学习进程替换,我们可以体会到多语言混搭的快乐,可以从C语言直接蹦到python ,也可以从c++里运行java代码。是不是很厉害!这是通过调度多个进程的效果,联系我们之前学习的进程,进程控制等概念。我们可以想要运行其他代码可以通过创建子进程来实现,但是这样也肯定是同一种语言,如果想要运行其他语言,那是不是有种方法可以调度一个进程来当做子进程呢???
我们开始今天的学习吧!

2 进程替换

2.1 替换函数

进程替换有六种以exec开头的函数,统称exec函数:

#include <unistd.h>`
int execl(const char *path, const char *arg, ...);//...代表可变参数 类似printf
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 *filename, char *const argv[],char* const envp[]);

我们来进行一下使用,来看看:

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 
  4 int main()
  5 {
  6   printf("textexec ... begin!\n");
  7 
  8   execl("/usr/bin/ls","ls","-l","-a",NULL);                                                                                                                                   
  9                                                                                                
 10   printf("textexec ... end!\n");                                                               
 11   return 0;                                                                                    
 12 }  

【Linux】开始学习进程替换吧!,一起学Linux吧!,linux,学习,运维,c++,服务器
可以看到执行了ls -l -a命令(最后的打印语句也没有进行),可是我执行的是我们的代码,怎么就运行了ls 这个程序呢?
原因就是:exec*系列函数可以执行起来新的程序,让进程通过exec函数把自己替换为一个全新的进程

2.2 替换原理

  • 用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支)
  • 子进程往往要调用一种exec函数以执行另一个程序。
  • 当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动 开始执行
  • 调用exec并不创建新进程,所以调用exec前后该进程的id并未改变
  • 没有创建新进程!!!

【Linux】开始学习进程替换吧!,一起学Linux吧!,linux,学习,运维,c++,服务器
我们知道 进程 = 内核数据结构 + 代码和数据 ,替换就是用新进程的代码与数据替换之前的代码与数据,注意不改变pid哦!
站在被替换进程的角度:本质就是这个程序别加载到内存里了!!!exec* 就类似一个Linux 上的加载函数。

而且我们不用关心exec*函数的返回值,只要替换成功了,就不会向后运行(也就用不到它的返回值了),只要继续运行那一定就是替换失败了!!!
那如果不想替换掉我们的程序,还想要打开一个新程序呢??? 我们接着向下看

2.3 单进程改为多进程

方法很简单,我们通过fork函数创建一个子进程,让子进程来执行我们的新程序不就可以了吗!

1 #include<stdio.h>  
  2 #include<unistd.h>   
  3 #include<stdlib.h>
  4 #include<sys/types.h>
  5 #include<sys/wait.h>
  6 
  7 
  8 int main()
  9 {
 10   printf("textexec ... begin!\n");
 11   
 12   pid_t id = fork();
 13   if(id == 0)
 14   {
 15     //child
 16     execl("/usr/bin/ls","ls","-l","-a",NULL);
 17     exit(1);
 18   }
 19 
 20   int status = 0;
 21   pid_t rid = waitpid(-1,&status,0);
 22 
 23   if(rid > 0)
 24   {
 25     printf("father wait success,child exit code:%d \n",WEXITSTATUS(status));                                                                                                  
 26   }                                                                                                                     
 27   printf("testexec ... end!\n");                                                                                        
 28                                                                                                                         
 29   return 0;                                                                                                             
 30 }          

这个程序中:我们通过fork创建了一个子进程,然后在子进程中进行进程替换。这样应该就可以运行ls命令还不会影响原本程序。来看效果:
【Linux】开始学习进程替换吧!,一起学Linux吧!,linux,学习,运维,c++,服务器
那么这样以后,创建子进程就变得非常有用了。我们可以通过子进程来完成对应任务:

  1. 让子进程完成父进程代码的一部分
  2. 让子进程执行一个全新的程序(会发生写时拷贝,建立全新的物理内存空间)

2.4 理解使用exec* 函数

这些函数原型看起来很容易混,但只要掌握了规律就很好记。

  • l(list) : 表示参数采用列表
  • v(vector) : 参数用数组
  • p(path) : 有p自动搜索环境变量PATH
  • e(env) : 表示自己维护环境变量

int execl (const char *path, const char *arg, …)

l 表示列表 list
两个参数分别代表:

  1. path (你想执行谁) : 我们执行的程序需要带路径
  2. arg(你想怎么执行) : 咳传多个 , 命令行里怎么运行就怎么写入!!! 举个例子:ls -a -l 所以我们传execl(“/usr/bin/ls” , “ls”,“-a”,“-l”) 。这样就像命令列表

通过这些函数也可以进行执行我们缩写的程序!!!

int execv (const char *path, char *const argv[])

v 表示数组 vector
这个方法就是把列表整合为一个数组,这样就直接传入一个数组(必须以NULL结尾!!!)就可以了:

char* const argv[] = 
{
	(char*)"ls",
	(char*)"-a",
	(char*)"-l",
	(char*)"--color",
	NULL
};
execv("/usr/bin/ls",argv);

是不是很想之前了解过的main函数参数!

int execvp(const char *file, char *const argv[])

带p含义是可以不传入文件路径,可以直接告诉exec*需要执行谁就可以了
本质就是:查找这个程序,系统会在系统环境变量PATH中的路径来寻找

char* const argv[] = 
{
	(char*)"ls",
	(char*)"-a",
	(char*)"-l",
	(char*)"--color",
	NULL
};
execvp("ls",argv);

这个 int execlp(const char *file, const char *arg, …) 同理!!!

execlp("ls" , "ls","-a","-l") 

int execle(const char *path, const char *arg, …,char *const envp[])

这个就就加上了环境变量,让我们支持自主传入

int execve(const char *filename, char const argv[],char const envp[]) 同理 !!!

int execvpe(const char *filename, char const argv[],char const envp[])

这让我们可以传入环境变量给子进程!!!当然也会有一批来着"爷爷进程"bash的环境变量!
envp的含义是全体替换环境变量,所以会有以下情况:

  1. 用全新的给子进程
  2. 用老的环境变量给子进程 char** environ
  3. 老的环境变量稍微修改传给子进程 调用 putenv ()函数
char* const argv[] = 
{
	(char*)"ls",
	(char*)"-a",
	(char*)"-l",
	(char*)"--color",
	NULL
};
//用全新的给子进程
char* const envp[] = 
{
	(char*)"HAHA=111111",
	(char*)"HEHE=222222",
	NULL
};
//putenv("HAHA=111111")
//putenv("HEHE=222222");
//老的环境变量稍微修改传给子进程

execvpe("./myprocess",argv , encp);
//char** environ
// execvpe("./myprocess",argv , environ);

注意

根据上面的用法使用,我们可以总结一下:

函数名 参数格式 是否带路径 是否使用当前环境变量
execl 列表 不是
execlp 列表
execle 列表 不是 不是,需要自己组装环境变量
execv 数组 不是
execvp 数组
execve 数组 不是 不是,需要自己组装环境变量

而且只有 execle 是系统调用!!!他们的关系如下:
【Linux】开始学习进程替换吧!,一起学Linux吧!,linux,学习,运维,c++,服务器文章来源地址https://www.toymoban.com/news/detail-844843.html

Thanks♪(・ω・)ノ谢谢阅读!!!

下一篇文章见!!!

到了这里,关于【Linux】开始学习进程替换吧!的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux进程控制【进程程序替换】

    ✨个人主页: Yohifo 🎉所属专栏: Linux学习之旅 🎊每篇一句: 图片来源 🎃操作环境: CentOS 7.6 阿里云远程服务器 Good judgment comes from experience, and a lot of that comes from bad judgment. 好的判断力来自经验,其中很多来自糟糕的判断力。 子进程 在被创建后,共享的是 父进程 的代码

    2024年01月17日
    浏览(70)
  • 【Linux】进程等待和替换——进程等待的原理、wait/waitpid方法、进程程序替换、进程替换原理、替换函数

    1.1进程等待的概念    进程等待指的是父进程等待子进程退出,以获取子进程的退出返回值,并释放子进程占用的资源。    当子进程先于父进程退出,但父进程没有关注子进程的退出状态时, 子进程会为了保存自己的退出状态而保持资源占用, 这种情况被称为“僵尸进

    2024年02月04日
    浏览(43)
  • [Linux 进程控制(二)] 进程程序替换

    首先,我们要认识到,我们之前fork()所创建的子进程,执行的代码,都是父进程的一部分(用if-else分流或者执行同样的代码)! 如果我们想让子进程执行新的程序呢? 执行全新的代码和访问全新的数据,不再和父进程有瓜葛,这种技术就叫做程序替换 ,下面我们就来学习一

    2024年03月14日
    浏览(50)
  • 【Linux】Linux进程控制及程序替换

    🍎 作者: 阿润菜菜 📖 专栏: Linux系统编程 在linux中fork是一个很重要的函数,它可以已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。 fork函数返回两个值,一个是子进程的进程号(pid),另一个是0。 父进程可以通过pid来区分自己和子进程,子进程可

    2024年02月02日
    浏览(45)
  • 【Linux进程控制】进程创建 | 进程终止 | 进程等待 | 进程替换

    【写在前面】 本文主要学习理解 fork 的返回值、写时拷贝的工作细节、为什么要存在写时拷贝;进程退出码、进程退出的场景及常见的退出方法、对比 man 2 _exit 和 man 3 exit;进程终止、操作系统怎么进行释放资源、池的概念;进程等待的价值、进程等待的方法 wait 和 waitpid

    2023年04月08日
    浏览(38)
  • Linux之进程控制&&进程终止&&进程等待&&进程的程序替换&&替换函数&&实现简易shell

    1.1 fork的使用 我们可以使用man指令来查看一下 子进程会复制父进程的PCB,之间代码共享,数据独有,拥有各自的进程虚拟地址空间。 这里就有一个代码共享,并且子进程是拷贝了父进程的PCB,虽然他们各自拥有自己的进程虚拟地址空间,数据是拷贝过来的,通过页表映射到

    2024年04月17日
    浏览(58)
  • 【Linux】Linux进程控制 --- 进程创建、终止、等待、替换、shell派生子进程的理解…

    柴犬: 你好啊,屏幕前的大帅哥or大美女,和我一起享受美好的今天叭😃😃😃 1. 在调用fork函数之后, 当执行的程序代码转移到内核中的fork代码后 ,内核需要分配 新的内存块 和 内核数据结构 给子进程, 内核数据结构包括PCB、mm_struct和页表,然后构建起映射关系 ,同时

    2024年01月16日
    浏览(58)
  • Linux :进程的程序替换

    目录 一、什么是程序替换 1.1程序替换的原理 1.2更改为多进程版本 二、各种exe接口 2.2execlp  ​编辑 2.2execv 2.3execle、execve、execvpe 用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种

    2024年04月10日
    浏览(35)
  • 【Linux】进程的程序替换

    目标:为了让子进程帮父进程执行特定的任务 具体做法:1. 让子进程执行父进程的一部分代码 红框中的代码实际上是父进程的代码,在没有执行fork之前代码就有了,在没有创建子进程之前,父进程的代码加载到内存了,子进程被创建出来是没有独立的代码,这个代码是父进

    2024年01月17日
    浏览(45)
  • 【Linux】—— 进程程序替换

    目录 序言 (一)替换原理 1、进程角度——见见猪跑  1️⃣ 认识 execl 函数 2、程序角度——看图理解 (二)替换函数 1、命名理解  2、函数理解 1️⃣execlp 2️⃣execv 3️⃣execvp 4️⃣execle 5️⃣execve 6️⃣execve (三)自制shell 总结 在前面的文章中,我已经详细的讲解了进程

    2024年02月12日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包