命令行参数环境变量和进程空间地址

文章目录

  • 命令行参数
  • 环境变量
  • 进程地址空间

正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能学习网站, 通俗易懂,风趣幽默,忍不住分享一下给大家。 点击跳转到网站。

命令行参数

什么是命令行参数?
我们平时写的代码中写写到的主函数main函数是可以有参数的。
在这里插入图片描述
在这里插入图片描述
我们可以看一下这段代码的运行结果。
在这里插入图片描述
我们可以看到我们输入的字符串被一空格为分隔符分成了若干个字串,并且argc就是字串的个数,argv中放的都是被分割出来的字串。而argv数组最后一个原始是存放的空的,有了这个东西,我们的程序就可以支持各种各样的命令行级别的指令选项的设置,也是为了让我们的一个程序对不同的选项做出不同的动作。

环境变量

环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。

常见的环境变量

我们在执行自己的可执行程序但是都需要加一个./,不然运行不要,系统找不到我们的可执行程序,但是在执行系统的命令是却不需要这样做,直接输入程序名称就可以运行,这是为什么?为什么系统的命令直接就可以执行我们的程序就必须要加一个./,我们直到不管是什么程序,系统要执行,就必须找到它,我们的执行不了而系统的可以执行只有一个原因,就是系统中一定存在默认的搜索路径。
这个默认的搜索路径就放在一个环境变量PATH中。Linux中可以使用$环境变量来查看环境变量中的内容。
在这里插入图片描述

所以PATH环境变量就是存放系统默认的搜索路径。只要我们将我们自己的程序的路径加到这个默认路径中,我们的进程也可以直接运行。

除了PATH环境变量外还有HOME,PWD等等很多环境变量。
在这里插入图片描述

其中HOME就是我们的家目录,PWD就是我们当前所处的目录。

这也就可以解释为为什么我们普通用户登录后是在/home/xxx,而root是在/root下的原因了。

在这里插入图片描述
系统中会存在大量的环境变量,每一个环境变量都有它自己特殊的用途,用来完成特定的系统功能。

在Linux中查看所有的环境变量命令是env。
在这里插入图片描述
我们也可以创建环境变量,在Linux中直接在命令行中使用 环境变量名=什么 就可以创建一个变量,不过这种变量不是环境变量叫做本地变量,我们需要用export导出一下才是环境变量,而且每一次我们重新登录服务器时,环境变量都会被更新,不会保留之前的操作,也就是说,就算我们修改了系统的环境变量也没关系,只需要重新登录一下云服务器就好了,那么为什么这样呢?

我们的命令行启动的进程都是shell/bash的子进程,子进程的命令行参数和环境变量都是父进程给我们传递的,而我们更改的是命令行内部的环境变量信息,而我们每一次重新登录都会给我们都会给我们形成新的bash解释器并且新的bash解释器自动读取新的环境变量表信息,所以我们可以大胆的推测,父进程的环境变量是以脚本配置的文件存在的。
而在我们目前的系统中,我们每一次登录我们的bash都会读取 .bash_profile文件,文件中的内容为我们形成一张环境变量表信息。
在这里插入图片描述

这个文件一般是存在我们的家目录中的。

我们在外面可以很好的获取环境变量,但是编码如何获取环境变量呢?

  1. 我们可以通过函数getenv来获取环境变量

在这里插入图片描述

  1. main函数是可以有第三个参数的,第三个参数就是环境变量表

在这里插入图片描述
这个环境变量表最后也是以null结尾的。

  1. C语言是有一个全局变量指向环境变量表的

在这里插入图片描述
我们可以直接使用envrion来获取环境变量。

在这里插入图片描述

环境变量通常具有全局属性,可以被子进程继承下去。

如果我们把PATH清空,我们会发现大部分命令都跑不了,但是还有一部分命令是可以跑的。
在这里插入图片描述
我们知道Linux是又C/C++写的,Linux中大部分命令都是子进程,但是也有一部分是Shell的一个函数。

所以Linux的命令就分为两种:

  1. 常规命令,Shell使用fork让子进程去执行的
  2. 内建命令,Shell命令行的一个函数

本地变量VS环境变量

本地变量只在bash内部有效,不会被子进程继承下去,而环境变量通过让所有子进程继承的方式实现自身的全局属性。

进程地址空间

对于我们C/C++程序员来说,内存空间一般分为如下几个区域:
在这里插入图片描述
其中堆和栈中间有一块很大的区域,堆是向上增长的,而栈是向下增长的,堆栈相对而生。我们创建的变量都是指向低地址的起始位置,变量的本质就是起始地址+偏移量的访问形式。那么这个东西就是我们平时在系统层面说的内存吗?我们可以先来看一个代码

#include <stdio.h>2 #include <sys/types.h>3 #include <unistd.h>                                                                                                                                                                                           4 int val = 10;5 int main()6 {7     pid_t id = fork();8 9     if(id == 0)10     {11         //子进程12         int cnt = 5;13         while(1)14         {15             if(cnt--==0)16             {17                 val = 5;18             }19             printf("i am child, i am pid %d, val = %d, &val = %p\n",getpid(),val,&val);20             sleep(1);21         }22     }23     else{24         while(1)25         {26             printf("i am parent, i am pid %d, val = %d, &val = %p\n",getpid(),val,&val);27             sleep(1);28         }29     }30     return 0;31 }

在这里插入图片描述

我们可以看到在5秒过后,父进程和子进程的val地址一样,但是里面的内容确不一样,那么就只有一个原因,就是他们一定不是物理内存。我们平时写代码用到的地址都是虚拟地址/线性地址。所以说上面的那个图不是内存,是进程地址空间!

在进程地址空间和物理内存中间存在一个叫页表的东西,而页表就是虚拟地址对应映射的物理地址,也就是说,我们每一个运行起来的进程都会有一个进程地址空间,并且都要在系统层面有自己的页表映射结构。
当我们的父进程创建子进程是,把它的进程地址空间和页表都给子进程拷贝一份,然后他们遵循写时拷贝的原则,当需要修改时,由于进程间是存在独立性的,所以子进程修改不能影响父进程,所以它就要重新再物理内存中开一块空间,然后修改自己的页表映射,所以才会存在同一块地址但是里面的东西是不一样的,本质就是他们映射的物理内存是不一样的。

在这里插入图片描述
地址空间每一个进程都有,所以OS也要对地址空间进行管理,所以地址空间就是一个内核的数据结构对象,就是一个内核结构体,里面需要对各个区域进行划分,我们每一个进程都可以使用00000000~FFFFFFFF这么大的内存,但是每个进程都不可能使用这么多的内存,因为就算你能用的了OS也不会允许,所以每一地址空间的内核数据结构中都是一些XXX_start,XXX_end的一些字段,表示一个区域的范围,如果某个需要增加,就修改字段就可以了。在Linux中这个虚拟地址空间就是叫做 struct mm_struct{}.

页表结构除了有虚拟地址->物理地址的映射外,在页表的后面还会存在两个字段,一个是该区域的访问权限字段,还有一个是映射的物理地址是否进行了空间分配&&是否存在内容,我们知道对于代码段和字符常量去的数据是不可以修改的,所以有人恶意修改的话,OS在页表层面就把它阻止了,所以我们平时对字符常量没法修改,本质还是它在页表映射中访问权限为只读,而第二个字段就是如果我们进程在阻塞的时候,OS可能会把我们的代码和数据暂时移除内存,所以我们在访问前要先看数据是否在内存中,如果不在内存中,OS就需要为我们开辟物理内存,把数据拷贝进来,然后进行页表映射,然后才能正常的执行我们的代码,该过程也叫做缺页中断。
CPU中是存在一个寄存器CR3存的是页表的地址(物理地址).
为什么存在进程地址空间呢?

  1. 让进程以统一的视角看待内存,所以任意一个进程,可以通过地址空间+页表将乱序的内存数据变为有序,分门别类规划好。
  2. 存在虚拟地址空间和页表,可以很好的进行访问内存的安全检查。
  3. 通过页表,进程管理只管页表左边的一部分,不管右边的,右边的由操作系统的内存管理来完成,所以可以很好的将进程管理和内存管理解耦。而且通过页表可以让相同地址的内容映射到不同的物理地址中,实现进程的独立性。

写时拷贝

在这里插入图片描述
我们知道创建子进程后,子进程和父进程数据和代码都是共享的,当有一方要修改时要发生写时拷贝,那么这个写时拷贝OS是什么时候做的呢?
其实在我们创建子进程时,代码和数据父进程和子进程都是共享的,并且他们在页表中的权限也被设置了为只读,所以当OS要进行写入时,会对它进程检查,如果是数据区是可以写入的,那么就写时拷贝,如果是代码区,本身就是只读的,就报错。所以当页表因为权限问题出错时,有可能是真的错了,也有可能不是出错,而是触发写时拷贝机制。

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

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

相关文章

存储任意类型

code /* * c17 std::any */#include <cstdint> #include <cstring> #include <cstdlib> #include <iostream> #include <thread> #include <chrono>namespace lxz {// T不为指针时 template<typename T> struct Data {Data(): data…

QT第六天

要求&#xff1a;使用QT绘图&#xff0c;完成仪表盘绘制&#xff0c;如下图。 素材 运行效果&#xff1a; 代码&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPainter> #include <QPen>QT_BEGIN_NAMESPACE name…

网络端口映射和端口转发的区别和联系

目 录 一、端口映射技术 1.1 原理 1.2 应用场景 1、远程访问 2、游戏主机 3、文件共享 4、监控视频共享 二、端口转发技术 2.1 原理 2.2 应用场景 1、网络负载均衡 2、网络安全 3、网络代理 三、端口映射和转发的实现方法 3.1 路由器配置 3.2 网络防火墙 …

跨平台兼容,无限可能:Apple Remote Desktop for Mac让远程控制更简单

Apple Remote Desktop for Mac是一款远程桌面管理软件&#xff0c;提供了一系列强大的功能&#xff0c;让用户可以轻松地管理和控制远程计算机。以下是该软件的一些主要功能和特点&#xff1a; 实时远程访问和控制&#xff1a;使用Apple Remote Desktop&#xff0c;用户可以在…

跟着pink老师前端入门教程-day05

七、CSS的引入方式 根据CSS样式书写的位置&#xff08;或者引入的方式&#xff09;&#xff0c;CSS样式表可以分为三大类 1. 行内样式表&#xff08;行内式&#xff09; 内部样式表&#xff08;内嵌样式表&#xff09;是写到HTML页面内部&#xff0c;将所有的CSS代码抽取出…

【Proteus仿真】【Arduino单片机】智能助眠机系统设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器&#xff0c;使用蜂鸣器闹铃模块、LCD1602显示模块、心率血氧模块、ADC模块、按键模块等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示传感器采…

HackTheBox - Medium - Linux - Mentor

Mentor Mentor 是一台中等难度的 Linux 机器&#xff0c;其路径包括在到达 root 之前在四个不同的用户之间切换。使用可暴力破解的社区字符串扫描“SNMP”服务后&#xff0c;会发现用于“API”端点的明文凭据&#xff0c;该端点被证明容易受到盲目远程代码执行的影响&#xff…

如何实现无公网ip远程访问内网本地BUG管理服务【内网穿透】

文章目录 前言1. 本地安装配置BUG管理系统2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射本地服务3. 测试公网远程访问4. 配置固定二级子域名4.1 保留一个二级子域名5.1 配置二级子域名6. 使用固定二级子域名远程 前言 BUG管理软件,作为软件测试工程师的必备工具之一。在…

精通Discord营销:多账号注册与管理,高效打造矩阵

Discord虽然是一个海外小众平台&#xff0c;但在Z世代群体来说却非常受欢迎。通常在游戏行业、年轻化的电商特定品类、软件等业务中&#xff0c;Discord的社群营销可以起到非常卓越的效果。但是&#xff0c;您必须学会管理不同的帐户&#xff0c;以构成矩阵打造社区&#xff0c…

更适合3D项目的UI、事件交互!纯国产数字孪生引擎持续升级中!!!

UI和事件交互是3D可视化项目中最常见的模块&#xff0c;主要用于信息添加、展示&#xff0c;用来确保按照用户需求呈现内容并完成交互。 平时工作在进行UI和交互设计时&#xff0c;经常出现以下问题&#xff1a;UI过于复杂导致3D项目内交互效率低下&#xff0c;或者是结合3D项目…

简单了解【多智能体强化学习(MARL)】

我们的现实生活中有着许多多智能体共同决策的场景&#xff0c;比如多机械臂协同&#xff0c;多个无人机或多个机器人完成某共同目标。下面介绍单智能体强化学习的进化&#xff0c;多智能体强化学习。 含义 多智能体系统中包含 m 个智能体&#xff0c;智能体共享环境&#xff…

【vsan数据恢复】vsan逻辑架构出现故障的数据恢复案例

VSAN数据恢复环境&#xff1a; 一套有三台服务器节点的VSAN超融合基础架构&#xff0c;每台服务器节点上配置2块SSD硬盘和4块机械硬盘。 每个服务器节点上配置有两个磁盘组&#xff0c;每个磁盘组使用1个SSD硬盘作为缓存盘&#xff0c;2个机械硬盘作为容量盘。三台服务器节点上…

c/c++的指针函数与函数指针

函数 定义&#xff1a; 函数是数学中的一个概念&#xff0c;它是定义在某个数集上的一个特殊的映射关系。函数将输入值&#xff08;或自变量&#xff09;映射到输出值&#xff08;或因变量&#xff09;。函数的输入和输出可以是任何类型的数据&#xff0c;如数字、字符串、数组…

ArcGIS Pro 如何新建布局

你是否已经习惯了在ArcGIS中数据视图和布局视图之间来回切换&#xff0c;到了ArcGIS Pro中却找不到二者之间切换的按钮&#xff0c;即使新建布局后却发现地图怎么却是一片空白。 这一切的一切都是因为ArcGIS Pro的功能框架完全不同&#xff0c;这里为大家介绍一下在ArcGIS Pro…

前端react入门day04-useEffect与Hook函数

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 useEffect 的使用 useEffect 的概念理解 useEffect 依赖项参数说明 useEffect — 清除副作用 自定义Ho…

Baichuan2百川模型部署的bug汇总

1.4bit的量化版本最好不要在Windows系统中运行&#xff0c;大概原因报错原因是bitsandbytes不支持window&#xff0c;bitsandbytes-windows目前仅支持8bit量化。 2. 报错原因是机器没有足够的内存和显存&#xff0c;offload_folder设置一个文件夹来保存那些离线加载到硬盘的权…

【DC-DC】APS54085降压恒流 高辉度调光降压恒流芯片

产品描述 APS54085 是一款 PWM 工作模式,高效率、 外围简单、内置功率 MOS 管&#xff0c;适用于 5-100V 输入的高精度降压 LED 恒流驱动芯片。最大电流 2.0A。 APS54085 可实现线性调光和 PWM 调光&#xff0c; 线性调光有效电压范围 0.52-2.55V. PWM 调光频率范围 100…

React Native实现QQ等级皇冠太阳星星的展示-代码示例

代码 function LevelGetImages(level: number) {let res []const marks [{ mod: 20, image: Images.setting.level_king },{ mod: 15, image: Images.setting.level_queen },{ mod: 10, image: Images.setting.level_moon },{ mod: 5, image: Images.setting.level_star },…

metinfo_6.0.0 任意文件读取漏洞复现

漏洞点为/include/thumb.php 一测&#xff1a;/include/thumb.php?dir..././http/..././config/config_db.php 二测&#xff1a;/include/thumb.php?dir.....///http/.....///config/config_db.php 三测&#xff1a;/include/thumb.php?dirhttp/.....///.....///config/conf…

geopandas 笔记:plot 的scheme

transbigdata 笔记&#xff1a;官方文档案例1&#xff08;出租车GPS数据处理&#xff09;-CSDN博客 3.3.1 节的内容的拓展&#xff0c;这里主要是比较各个scheme的效果 主代码为&#xff1a;修改的就是第二行scheme的内容 plt.figure(1,(16, 6), dpi300) schemebox_plot #图…