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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/665556.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

禁止 ios H5 中 bounces 滑动回弹效果

在开发面向 iOS 设备的 HTML5 应用时&#xff0c;控制页面的滚动行为至关重要&#xff0c;特别是禁用在 Safari 中默认的滑动回弹效果。本文旨在提供一个简洁明了的解决方案&#xff0c;帮助开发者在特定的 Web 应用中禁用这一效果。 1. 什么是滑动回弹效果&#xff1f; 在 iO…

C++输出地址

下面是一段输出地址的程序。 #include <bits/stdc.h> using namespace std;int main() {int s;cout << &s;//原地址return 0; }假如有一个人&#xff08;的朋友&#xff09;后来了&#xff0c;他也想住进的房间&#xff0c;我们可以这样&#xff1a; #includ…

【数据结构】链表OJ面试题2(题库+解析)

1.前言 前五题在这http://t.csdnimg.cn/UeggB 休息一天&#xff0c;今天继续刷题&#xff01; 2.OJ题目训练 1. 编写代码&#xff0c;以给定值x为基准将链表分割成两部分&#xff0c;所有小于x的结点排在大于或等于x的结点之前 。链表分割_牛客题霸_牛客网 思路 既然涉及…

gif动图的裁剪实现思路

项目需求(对app的轮播,以及banner和咨询的图片进行裁剪):前期实现使用用vue-cropper插件对图片进行插件,----后续需求需要裁剪gif动图(vue-cropper、微信自带的截图工具,以及fastStone截图工具,都只能截取静态图片,打开动图时只显示某一帧的静态图片),所以需要研究为什么vue-cr…

机器学习——集成学习

&#x1f4d5;参考&#xff1a;ysu老师课件西瓜书 期末复习笔记 1.集成学习的基本概念 集成学习&#xff08;ensemble learing&#xff09;通过构建并结合多个学习器来完成学习任务。 有时也被称为多分类器系统&#xff08;multi-classifier system&#xff09;、基于委员会的…

Spring Cloud Stream解密:流式数据在微服务中的魔力

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 Spring Cloud Stream解密&#xff1a;流式数据在微服务中的魔力 前言Spring Cloud Stream基础&#xff1a;微服务中的数据流动Binder概念与使用&#xff1a;连接流的音符消息序列化与反序列化&#xf…

【消息队列】kafka整理

kafka整理 整理kafka基本知识供回顾。

Leetcode刷题笔记题解(C++):99. 恢复二叉搜索树

思路&#xff1a; 二叉搜索树的中序遍历是递增序列&#xff0c;可以在中序遍历中记录两个需要交换的节点&#xff0c;直到遍历完毕之后&#xff0c;对两个节点的值进行交换即可得到正确的二叉搜索树 比如中序序列为 1 2 3 7 5 6 4&#xff08;7比5大记录7为x&#xf…

每日OJ题_算法_模拟③_力扣6. Z 字形变换

目录 力扣6. Z 字形变换 解析代码 力扣6. Z 字形变换 6. Z 字形变换 难度 中等 将一个给定字符串 s 根据给定的行数 numRows &#xff0c;以从上往下、从左到右进行 Z 字形排列。 比如输入字符串为 "PAYPALISHIRING" 行数为 3 时&#xff0c;排列如下&#xff…

以太网帧格式及ARP协议简介

在以太网中&#xff0c;一个主机和另一个主机进行通信&#xff0c;必须要知道目的主机的MAC地址&#xff08;物理地址&#xff09;&#xff0c;只要知道目的主机的IP地址&#xff0c;就可以通过ARP协议获取目的主机的MAC地址。 1、ARP协议简介 ARP&#xff08;Address Resolut…

处理安装uni-ui依赖一直安装不上

根据官方的文档去安装&#xff0c;我这边把npm换成了pnpm。 搞了一个小时没搞明白为什么下载不下来依赖&#xff0c;原因是镜像的问题。 处理方式&#xff1a;安装了cnpm&#xff0c;去访问国内镜像 安装cnpm&#xff0c;使用国内镜像 npm install -g cnpm --registryhttps…

react 之 useCallback

简单讲述下useCallback的使用方法&#xff0c;useCallback也是用来缓存的&#xff0c;只不过是用于做函数缓存 // useCallbackimport { memo, useCallback, useState } from "react"const Input memo(function Input ({ onChange }) {console.log(子组件重新渲染了…

【第二十二课】最短路:多源最短路floyd算法(acwing-852 spfa判断是否存在负环 / acwing-854 / c++代码)

目录 acwing-852 代码如下 一些解释 acwing-854 foyld算法思想 代码如下 一些解释 acwing-852 在spfa求最短路的算法基础上进行修改。 代码如下 #include<iostream> #include<cstring> #include<algorithm> #include<queue> using names…

百分点科技:《数据科学技术: 文本分析和知识图谱》

科技进步带来的便利已经渗透到工作生活的方方面面&#xff0c;ChatGPT的出现更是掀起了新一波的智能化浪潮&#xff0c;推动更多智能应用的涌现。这背后离不开一个朴素的逻辑&#xff0c;即对数据的收集、治理、建模、分析和应用&#xff0c;这便是数据科学所重点研究的对象——…

Python itertools模块:生成迭代器(实例分析)

itertools 模块中主要包含了一些用于生成迭代器的函数。在 Python 的交互式解释器中先导入 itertools 模块&#xff0c;然后输入 [e for e in dir(itertools) if not e.startswith(_)] 命令&#xff0c;即可看到该模块所包含的全部属性和函数&#xff1a; >>> [e for …

【单片机毕业设计6-基于stm32c8t6的智能衣柜系统】

【单片机毕业设计6-基于stm32c8t6的智能衣柜系统】 前言一、功能介绍二、硬件部分三、软件部分总结 前言 &#x1f525;这里是小殷学长&#xff0c;单片机毕业设计篇6基于stm32的智能衣柜系统 &#x1f9ff;创作不易&#xff0c;拒绝白嫖可私 一、功能介绍 -------------------…

Vue 上门取件时间组件

本文使用vue2.0elementui 制作一个上门取件时间组件&#xff0c;类似顺丰&#xff0c;样式如下&#xff1a; 大概功能&#xff1a;点击期望上门时间&#xff0c;下面出现一个弹框可以选择时间&#xff1a; 首先我们定义一些需要的数据&#xff1a; data() {return {isDropdown…

Java 集合List相关面试题

&#x1f4d5;作者简介&#xff1a; 过去日记&#xff0c;致力于Java、GoLang,Rust等多种编程语言&#xff0c;热爱技术&#xff0c;喜欢游戏的博主。 &#x1f4d7;本文收录于java面试题系列&#xff0c;大家有兴趣的可以看一看 &#x1f4d8;相关专栏Rust初阶教程、go语言基…

C++ 动态规划 分组背包问题

有 N 组物品和一个容量是 V 的背包。 每组物品有若干个&#xff0c;同一组内的物品最多只能选一个。 每件物品的体积是 vij &#xff0c;价值是 wij &#xff0c;其中 i 是组号&#xff0c;j 是组内编号。 求解将哪些物品装入背包&#xff0c;可使物品总体积不超过背包容量&a…

2024美赛数学建模ABCDEF题思路代码

--------------------2024美国大学生数学建模竞赛&#xff08;美赛&#xff09;思路&代码---------------------------- 赛题翻译&#xff1a;2024美赛ABCDEF赛题翻译 问题A&#xff08;数据分析题&#xff09;&#xff1a;资源可用性和性别比例&#xff08;MCM&#xff09…