【Linux系统化学习】进程替换

2024-02-03 22:04

本文主要是介绍【Linux系统化学习】进程替换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

进程程序替换 

替换原理

​编辑替换函数

函数解释

命名理解

函数使用

execl

execlp

 execv

execvp

调用其它程序


进程程序替换 

替换原理

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

替换函数

其实含有六种以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[]);

上面这些函数可以通过我们传递的参数,进行程序替换。、

  • const char *arg:可执行程序的命令行参数(注:要以NULL结尾,表示参数传递结束)
  • const char* path:可执行程序的位置
  • const char *file: 可执行程序的名称
  • char *const argc[ ]:可执行程序命令行参数形成的指针数组
  • char *const envp[ ]:环境变量

函数解释

  • 这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。
  • 如果调用出错则返回-1
  • 所以exec函数只有出错的返回值而没有成功的返回值

命名理解

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


函数使用

execl

我们知道在Linux系统中的指令其实也是一个程序,因此我们可以将我们的指令使用上面的函数进行替换。理论可行,实践操作。

  1 #include<stdio.h>2 #include<unistd.h>3 int main()4 {5     printf("pid : %d ,exec command begin\n",getpid());6     execl("/usr/bin/ls","ls","-a","-l",NULL);7     printf("pid: %d , exec commamd after\n",getpid() );                                 8     return 0;                                                                  9 } 

现象:

  • 在main函数中,使用exec函数执行了我们Linux下的ls指令
  • main函数中最后一句话没有执行

对现象的解释:

当我们运行我们编写的可执行程序时,操作系统首先会自动生成PCB结构体、进程地址空间(虚拟地址)、页表;将我们可执行程序中的代码通过页表一一对应到物理地址中。当我们执行到exec函数时,操作系统又将页表对应的物理空间中的内容替换成为exec中所要替换的程序。

程序替换成功后,就开始执行替换成功后的程序。前面我们讲过每个程序都有一个eip数据(进程运行计数器寄存器),因此会从开始执行替换后的程序;前面的文章我们又说过每个进程都会有退出码代表程序完成的怎么样;所以下面的一句话就不会执行。或者也可以这样理解:程序替换成功后原来的代码都会被覆盖掉。

总结:

  • 第二个参数其实就是我们在Linux终端怎么执行的指令,将各个部分拆开作为函数的参数。 
  • 并不会创建新的进程。

execlp

 1 #include<stdio.h>2 #include<unistd.h>3 int main()4 {5     printf("pid : %d ,exec command begin\n",getpid());6     execlp("ls","ls","-a","-l",NULL);                                                   7    // execl("/usr/bin/ls","ls","-a","-l",NULL);8     printf("pid: %d , exec commamd after\n",getpid() );9     return 0;10 }

 execv

   1 #include<stdio.h>2 #include<unistd.h>3 int main()4 {5     printf("pid : %d ,exec command begin\n",getpid());6     char* const argv[]={                                                              
W>  7         "ls",
W>  8         "-a",
W>  9         "-l",10         NULL11     };12     execv("/usr/bin/ls",argv);13    // execlp("ls","ls","-a","-l",NULL);14    // execl("/usr/bin/ls","ls","-a","-l",NULL);15     printf("pid: %d , exec commamd after\n",getpid() );16     return 0;17 }~

execvp

    1 #include<stdio.h>2 #include<unistd.h>3 int main()4 {5     printf("pid : %d ,exec command begin\n",getpid());6     char* const argv[]={
W>  7         "ls",
W>  8         "-a",
W>  9         "-l",10         NULL 11     };12         execvp(argv[0],argv);                                                         13    //  execv("/usr/bin/ls",argv);                                               14    // execlp("ls","ls","-a","-l",NULL);                                         15    // execl("/usr/bin/ls","ls","-a","-l",NULL);                                 16     printf("pid: %d , exec commamd after\n",getpid() );                         17     return 0;                                                                   18 }

 


调用其它程序

上面我们使用exec函数调用Linux下的指令,指令也是程序。我们写的可执行程序也是程序那么我们能否使用exec函数来替换我们自己写的可执行程序呢?理论可行,实践操作。

我们在同一目录下编写一个简单的C++程序,编译好的可执行程序也在这个目录下,尝试替换这个C++程序。

//test.cpp  1 #include<iostream>2 using namespace std;3 int main()4 {5     cout<<"hello C++"<<endl;6     cout<<"hello C++"<<endl;7     cout<<"hello C++"<<endl;8     cout<<"hello C++"<<endl;9     cout<<"hello C++"<<endl;                                                            10     return 0;11 }
//test2-8-1.c1 #include<stdio.h>2 #include<stdlib.h>3 #include<unistd.h>4 #include<sys/types.h>5 #include<sys/wait.h>6 int main()7 {8     pid_t id = fork();9     if(id==0)10     {11         //child12         printf("pid :%d ,exec command begin \n",getpid());13         sleep(3);14         execl("./mytest1","mytest1",NULL);                                              15         printf("pid: %d ,exec command after\n",getpid());16     }17     else18     {19         pid_t rid = waitpid(-1,NULL,0);20         if(rid>0)21         {22             printf("wait success ,rid : %d \n",rid);23         }24     }25     return 0;26 }

 

结论:

  • 可以通过exec函数替换我们自己编写的可执行程序。
  • 其实不仅可以调用C++编写的程序,也可以调用shell、python、Java。编写的脚本/可执行程序因为不管什么语言编写的可执行程序,执行起来对于操作系统来说就是进程;所以可以使用exec进行各种语言编写程序的替换
  • exec这一批函数其实就是在操作系统中进程的加载器 。

还有一个包含环境变量参数的函数,我会在下篇文章给大家介绍;并且在下篇文章中带大家完成一个我们自己的shell。

今天对Linux下进程的替换的分享到这就结束了,希望大家读完后有很大的收获,也可以在评论区点评文章中的内容和分享自己的看法;个人主页还有很多精彩的内容。您三连的支持就是我前进的动力,感谢大家的支持!!! 

这篇关于【Linux系统化学习】进程替换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/675550

相关文章

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法

《ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法》本文介绍了Elasticsearch的基本概念,包括文档和字段、索引和映射,还详细描述了如何通过Docker... 目录1、ElasticSearch概念2、ElasticSearch、Kibana和IK分词器部署

Linux流媒体服务器部署流程

《Linux流媒体服务器部署流程》文章详细介绍了流媒体服务器的部署步骤,包括更新系统、安装依赖组件、编译安装Nginx和RTMP模块、配置Nginx和FFmpeg,以及测试流媒体服务器的搭建... 目录流媒体服务器部署部署安装1.更新系统2.安装依赖组件3.解压4.编译安装(添加RTMP和openssl模块

linux下多个硬盘划分到同一挂载点问题

《linux下多个硬盘划分到同一挂载点问题》在Linux系统中,将多个硬盘划分到同一挂载点需要通过逻辑卷管理(LVM)来实现,首先,需要将物理存储设备(如硬盘分区)创建为物理卷,然后,将这些物理卷组成... 目录linux下多个硬盘划分到同一挂载点需要明确的几个概念硬盘插上默认的是非lvm总结Linux下多

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.

Linux环境变量&&进程地址空间详解

《Linux环境变量&&进程地址空间详解》本文介绍了Linux环境变量、命令行参数、进程地址空间以及Linux内核进程调度队列的相关知识,环境变量是系统运行环境的参数,命令行参数用于传递给程序的参数,... 目录一、初步认识环境变量1.1常见的环境变量1.2环境变量的基本概念二、命令行参数2.1通过命令编程

Linux之进程状态&&进程优先级详解

《Linux之进程状态&&进程优先级详解》文章介绍了操作系统中进程的状态,包括运行状态、阻塞状态和挂起状态,并详细解释了Linux下进程的具体状态及其管理,此外,文章还讨论了进程的优先级、查看和修改进... 目录一、操作系统的进程状态1.1运行状态1.2阻塞状态1.3挂起二、linux下具体的状态三、进程的

Linux编译器--gcc/g++使用方式

《Linux编译器--gcc/g++使用方式》文章主要介绍了C/C++程序的编译过程,包括预编译、编译、汇编和链接四个阶段,并详细解释了每个阶段的作用和具体操作,同时,还介绍了调试和发布版本的概念... 目录一、预编译指令1.1预处理功能1.2指令1.3问题扩展二、编译(生成汇编)三、汇编(生成二进制机器语

Rsnapshot怎么用? 基于Rsync的强大Linux备份工具使用指南

《Rsnapshot怎么用?基于Rsync的强大Linux备份工具使用指南》Rsnapshot不仅可以备份本地文件,还能通过SSH备份远程文件,接下来详细介绍如何安装、配置和使用Rsnaps... Rsnapshot 是一款开源的文件系统快照工具。它结合了 Rsync 和 SSH 的能力,可以帮助你在 li