[Linux][环境变量][进程地址空间]详细解读

news2024/11/25 21:31:59

目录

  • 1.环境变量
    • 1.基本概念
    • 2.常见环境变量
    • 3.查看环境变量的方法
    • 4.测试PATH
    • 5.测试HOME
    • 6.和环境变量相关的命令
    • 7.环境变量的组织方式
    • 8.通过代码如何获取环境变量
    • 9.通过系统调用获取或设置环境变量
    • 10.环境变量通常是具有全局属性
  • 2.进程地址空间
    • 0.这里的地址空间,是物理内存吗?
    • 1.为什么不能直接访问物理内存?
    • 2.分页&虚拟地址空间
    • 3.扩展内容1
    • 4.为什么要有地址空间?
  • 3.重新理解什么是挂起?

1.环境变量

1.基本概念

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

2.常见环境变量

  • PATH : 指定命令的搜索路径
  • HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
  • SHELL : 当前Shell,它的值通常是/bin/bash

3.查看环境变量的方法

echo $NAME // NAME:你的环境变量名称

4.测试PATH

  1. 创建hello.c文件
  2. 对比./hello执行和之间hello执行
  3. 为什么有些指令可以直接执行,不需要带路径,而我们的二进制程序需要带路径才能执行?
  4. 将我们的程序所在路径加入环境变量PATH当中, export PATH=$PATH:hello程序所在路径
    • 有效期限:临时改变,只能在当前的终端窗口中有效,当前窗口关闭后就会恢复原有的path配置

5.测试HOME

  • 用root和普通用户,分别执行 echo $HOME,对比差异
  • 执行 cd ~; pwd,对应 ~ 和 HOME 的关系

6.和环境变量相关的命令

  • echo:显示某个环境变量值
  • export:设置一个新的环境变量
  • env:显示所有环境变量
  • unset:清除环境变量
  • set:显示本地定义的shell变量和环境变量

7.环境变量的组织方式

  • 每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串
    请添加图片描述

8.通过代码如何获取环境变量

  • 命令行第三个参数
int main(int argc, char *argv[], char *env[])
{
    int i = 0;
    for (; env[i]; i++)
    {
        printf("%s\n", env[i]);
    }
    return 0;
}
  • 通过第三方变量environ获取
    • libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时要用extern声明
int main(int argc, char *argv[])
{
    extern char **environ;
    int i = 0;
    for (; environ[i]; i++)
    {
        printf("%s\n", environ[i]);
    }
    return 0;
}

9.通过系统调用获取或设置环境变量

  • putenv
  • getenv
int main()
{
    printf("%s\n", getenv("PATH"));
    return 0;
}
  • 常用getenv和putenv函数来访问特定的环境变量

10.环境变量通常是具有全局属性

  • 子进程的环境变量是从父进程继承来的 --> 环境变量具有全局属性
    • 默认情况下,所有的环境变量都会被子进程继承
int main()
{
    char *env = getenv("MYENV");
    if (env)
    {
        printf("%s\n", env);
    }
    return 0;
}
  • 直接查看,发现没有结果,说明该环境变量根本不存在
    • 导出环境变量 – export MYENV=“hello world”
    • 再次运行程序,发现结果有了!
    • 说明:环境变量是可以被子进程继承下去的!
    • 如果只进行 MYENV=“helloworld”,不调用export导出,再用我们的程序查看,会有什么结果?为什么?
      • 此时MYENV只是一个普通变量

2.进程地址空间

请添加图片描述

0.这里的地址空间,是物理内存吗?

  • 不是物理内存!
int g_val = 0;
int main()
{
    pid_t id = fork();
    if (id < 0)
    {
        perror("fork");
        return 0;
    }
    else if (id == 0)
    {
        // child,子进程肯定先跑完,也就是子进程先修改,完成之后,父进程再读取
        g_val = 100;
        printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
    }
    else
    { 
        // parent
        sleep(3);
        printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
    }
    sleep(1);
    return 0;
}
  • 输出结果:
child[3046]: 100 : 0x80497e8
parent[3045]: 0 : 0x80497e8
  • 综上发现,父子进程,输出地址是一致的,但是变量内容不一样!可得出如下结论:
    • 变量内容不一样,所以父子进程输出的变量绝对不是同一个变量
    • 但地址值是一样的,说明,该地址绝对不是物理地址!
      • 在Linux地址下,这种地址叫做虚拟地址
    • 在用C/C++所看到的地址,全部都是虚拟地址!
      • 物理地址,用户一概看不到,由OS统一管理,OS必须负责将虚拟地址转化成物理地址
  • 发生了写时拷贝

1.为什么不能直接访问物理内存?

  • 内存本身是随时可以被读写的
    • 比如有一个指针,成了野指针,通过它,访问了别的进程的数据,并且篡改了其数据
    • 这样特别不安全!

2.分页&虚拟地址空间

请添加图片描述

  • 上图可看出,同一个变量,地址相同,其实是虚拟地址相同,内容不同其实是被映射到了不同的物理地址
  • 地址空间是一种内核数据结构(mm_struct),它里面至少要有:各个区域的划分
  • 地址空间和页表(用户级)是每一个进程都私有一份
    • 只要保证,每一个进程的页表,映射的是物理内存的不同区域,就能做到,进程之间不会互相干扰,保证进程的独立性

3.扩展内容1

  • 当程序在编译的时候,形成可执行程序的时候,没有被加载到内存中的时候,程序的内部,有地址吗?
    • 可执行程序其实在编译的时候,内部已经有地址了
  • 地址空间不要仅仅理解成为是OS内部要遵守的,其实编译器也要遵守
    • 即编译器编译代码的时候,就已经给用户形成了各个区域,如代码区,数据区等
    • 并且,采用和Linux内核中一样的编址方式,给每一个变量,每一行代码都进行了编址
    • 故,程序在编译的时候,每一个字段早已经具有了一个虚拟地址
    • 程序内部的地址,依旧用的是编译器编译好的虚拟地址,当程序加载到内存的时候,每行代码,每个变量便具有了一个外部的物理地址
    • 那么,当CPU读到指令的时候,指令内部也有地址,这个地址是物理地址还是虚拟地址?
      • 是虚拟地址!

4.为什么要有地址空间?

  • 凡是非法的访问或者映射,OS都会识别到,并且终止这个进程 --> 有效的保护了物理内存
    • 因为地址空间和页表是OS创建并维护的,也就意味着凡是想使用地址空间和页表进行映射,也一定要在OS的监管之下来进行访问
    • 也便保护了物理内存中的所有合法数据,包括各个进程以及内核的相关有效数据
  • 因为有地址空间&页表映射的存在,物理内存可以对未来的数据进行任意位置加载
    • 正因此,物理内存的分配就可以和进程的管理,做到没有关系
      • 即:(内存管理模块 vs 进程管理模块) --> 完成了解耦合
    • 所以,在C/C++中,new/malloc空间的时候,本质是在哪里申请的?
      • 实质是在虚拟空间中申请的
    • 但倘若申请了空间,如果不立马使用,是不是造成了空间的浪费?
      • 是的
    • 本质上,(因为有地址空间的存在,所以上层申请空间,其实是在地址空间上申请的,物理内存甚至可以一个字节都不给你!而当你真正进行对物理地址空间访问的时候,才执行内存的相关管理算法,帮你申请内存,构建页表映射关系),然后再让你进行内存的访问
      • 这一整套流程是操作系统自动完成的,用户/进程,都完全0感知
      • 此举为延迟分配内存的策略,提高了整机的效率
        • 使得几乎内存的有效使用是100%
  • 因为在物理内存中,理论上可以任意位置加载,所以物理内存中的几乎所有的数据和代码在内存中都是乱序的
    • 但是,因为页表的存在,它可以将地址空间上的虚拟地址和物理地址进行映射,所以在进程的视角,所有的内存分布都是有序的!
      • 地址空间+页表的存在,可以将内存分布有序化
    • 可以理解成,地址空间是OS给进程画的大饼
      • 进程要访问物理内存中的数据和代码,可能目前并没有在物理内存中,同样的,也可以让不同的进程映射到不同的物理内存,这样是不是便很容易做到,进程独立性的实现?
        • 进程的独立性,可以通过地址空间+页表的方式实现
      • 因为有地址空间的存在,每一个进程都认为自己拥有4GB空间(x32),并且各个区域是有序的,进而可以通过页表映射到不同的区域,来实现进程的独立性。每一个进程都不知道,也不需要知道其他进程的存在!

3.重新理解什么是挂起?

  • 加载本质就是创建进程,那么是不是必须非得立马把所有的程序的代码和数据加载的内存中,并创建内核数据结构建立映射关系?
    • 不是
    • 在最极端的情况下,甚至只有内核数据结构被创建出来
      • 即:新建状态
  • 页表映射的时候,映射的可不仅仅是内存,磁盘中的位置,也可以映射
  • 理论上,可以实现对程序的分批加载
  • 既然可以分批加载,可以分批换出吗?
    • 当然可以
  • 甚至,这个进程短时间不会再执行了,比如阻塞
  • 进程的数据和代码被换出了,就叫做挂起

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

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

相关文章

【感谢】心怀感恩,共赴知识之旅——致每一位陪伴我突破百万总访问量的您

小伙伴朋友们&#xff1a; 此刻&#xff0c;我怀着无比激动与深深感激的心情&#xff0c;写下这篇特别的博文。今天&#xff0c;我的CSDN总访问量成功突破了百万大关&#xff0c;这不仅是一个数字的跨越&#xff0c;更是你们对我的支持、信任与鼓励的有力见证。在此&#xff0…

CNN家族的族谱!

没有过时的技术&#xff0c;只是看什么样的应用场景&#xff0c;某些场景下&#xff0c;老技术也能焕发光彩&#xff01; 发展历程 CNN思想起源——喵星人的视觉系统 20世纪60年代左右&#xff0c;加拿大神经科学家David H. Hubel和Torsten Wisesel发现了猫的视觉中枢里存在感…

SAP_ABAP_MM_PO审批_队列实践SMQ1

SAP ABAP 顾问&#xff08;开发工程师&#xff09;能力模型-CSDN博客文章浏览阅读1k次。目标&#xff1a;基于对SAP abap 顾问能力模型的梳理&#xff0c;给一年左右经验的abaper 快速成长为三年经验提供超级燃料&#xff01;https://blog.csdn.net/java_zhong1990/article/det…

Python - 深度学习系列32 - glm2接口部署实践

说明 前阵子&#xff0c;已经对glm2的接口部署做了镜像化。本次的目的是&#xff1a; 1 测试在隔了一阵子&#xff08;忘记&#xff09;的情况下&#xff0c;快速部署时是否有障碍&#xff0c;是不是足够方便2 在算网机环境下&#xff0c;能否快速的实现部署。仅考虑文件方式…

策略模式【行为模式C++】

1.概述 策略模式是一种行为设计模式&#xff0c; 它能让你定义一系列算法&#xff0c; 并将每种算法分别放入独立的类中&#xff0c; 以使算法的对象能够相互替换。 策略模式通常应用于需要多种算法进行操作的场景&#xff0c;如排序、搜索、数据压缩等。在这些情况下&#x…

D-LinkNAS 远程命令执行漏洞(CVE-2024-3273)RCE漏

声明&#xff1a; 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任。 简介 D-LinkNAS是由D-Link公司制造的网络附加存储设备。…

有趣的css - 动态雷达扫描

大家好&#xff0c;我是 Just&#xff0c;这里是「设计师工作日常」&#xff0c;今天分享的是使用 css 实现一个动态的雷达扫描&#xff0c;快学起来吧&#xff01; 《有趣的css》系列最新实例通过公众号「设计师工作日常」发布。 目录 整体效果核心代码html 代码css 部分代码…

产品推荐 | 瑞苏盈科基于立体帧捕捉和视频处理应用的火星Mars EB1开发板

01 产品概述 火星Mars EB1底板是为火星Mars系列FPGA和SoC核心板设计的通用底板&#xff0c;非常适用于立体帧捕捉和视频处理应用&#xff0c;可以为构建基于FPGA的定制化硬件系统提供一个良好的基础和开端。 02 核心亮点 ■ 与所有火星Mars系列FPGA和SoC核心板兼容 ■ 适用…

2024mathorcup数学建模C题思路分析-物流网络分拣中心货量预测及人员排班

# 1 赛题 C 题 物流网络分拣中心货量预测及人员排班 电商物流网络在订单履约中由多个环节组成&#xff0c;图 ’ 是一个简化的物流 网络示意图。其中&#xff0c;分拣中心作为网络的中间环节&#xff0c;需要将包裹按照不同 流向进行分拣并发往下一个场地&#xff0c;最终使包裹…

FME学习之旅---day23

我们付出一些成本&#xff0c;时间的或者其他&#xff0c;最终总能收获一些什么。 教程&#xff1a;地理数据库入门 FME 支持读取和写入不同的地理数据库格式;这包括文件地理数据库、个人地理数据库和 ArcSDE 地理数据库。支持矢量和栅格数据类型。在本教程中&#xff0c;我们…

Understanding Flink

Flink 下载&#xff1a; mkdir ~/flink && cd ~/flinkwget --no-check-certificate https://archive.apache.org/dist/flink/flink-1.15.3/flink-1.15.3-bin-scala_2.12.tgz wget --no-check-certificate https://repo1.maven.org/maven2/com/ververica/flink-sql-co…

PHP+MySQL组合开发 易企秀H5场景源码系统 带完整的安装代码包以及搭建教程

在数字化时代&#xff0c;企业对于宣传与推广的需求日益增长&#xff0c;而H5页面作为一种轻量级、跨平台的宣传方式&#xff0c;深受企业青睐。为了满足企业对于H5页面制作的需求&#xff0c;我们基于PHPMySQL组合开发了一套易企秀H5场景源码系统&#xff0c;并提供了完整的安…

PTA(题目集一 题目 代码 C++ 注解)

目录 题目一&#xff1a; 代码&#xff1a; 题目二&#xff1a; 代码&#xff1a; 题目三&#xff1a; 代码&#xff1a; 题目四&#xff1a; 代码&#xff1a; 题目五&#xff1a; 代码&#xff1a; 题目六&#xff1a; 代码&#xff1a; 题目七&#xff1a; 代…

VM虚拟机Linux系统Redhat7.4版本进行网络配置

日常中自己搭建的虚拟机一般用到两种网络方式&#xff0c;第一种是仅主机模式、还有一种是NAT模式。 1、仅主机模式&#xff1a;可以和自己本地电脑&#xff0c;或者虚拟机和虚拟机之间进行网络通信&#xff0c;相当于一个局域网&#xff0c;是不能连接外网的。 2、NAT模式&a…

Leetcode刷题之消失的数字(C语言版)

Leetcode刷题之消失的数字&#xff08;C语言版&#xff09; 一、题目描述二、题目解析 一、题目描述 数组nums包含从0到n的所有整数&#xff0c;但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗&#xff1f; 注意&#xff1a;本题相对书上原题稍作…

BIM信息如何整合到可视化大屏中,告诉你步骤。

BIM&#xff08;Building Information Modeling&#xff09;是一种数字化建筑信息模型技术&#xff0c;可以将建筑物的设计、施工和运营过程进行集成和管理。将BIM整合到可视化大屏中可以提供更直观、全面的建筑信息展示和分析。 BIM&#xff08;建筑信息模型&#xff09;可以通…

SFP光模块和媒体转换器的区别

SFP光模块和媒体转换器都是光电转换设备。它们是否可以互换使用&#xff1f;它们之间有什么区别&#xff1f; SFP光模块与媒体转换器&#xff1a;它们是什么&#xff1f; SFP模块是一种可热插拔的光模块&#xff0c;用于连接网络交换机。它可以将电信号转换为光信号&#xff…

Doris 内网安装部署,基于 CentOS 7

实测 CentOS 7.6 和 7.9都可用&#xff0c;CentOS安装包为&#xff1a;标准安装盘DVD版&#xff0c;如果系统安装的是精简版&#xff0c;需要挂载DVD版或者自行下载依赖。 参考文档 快速开始 - Apache Doris Doris 下载地址&#xff1a;2.1.1 ( Latest ) -> x64 ( avx2 )…

spring.rabbitmq.listener.simple.default-requeue-rejected = false 和放入死信队列的区别

目录 一、场景 二、使用 spring.rabbitmq.listener.simple.default-requeue-rejected false 2.1 特点 三、 放入死信队列 四、两种区别 一、场景 当我们使用RabbitMq的时候&#xff0c;我们如果业务中有异常&#xff0c;很有可能造成死循环&#xff0c;因为 在RabbitMQ和…

TSINGSEE青犀边缘计算AI智能分析网关V4客流统计算法的配置步骤及使用

TSINGSEE青犀AI智能分析网关V4内置了近40种AI算法模型&#xff0c;支持对接入的视频图像进行人、车、物、行为、烟火等实时检测分析&#xff0c;上报识别结果&#xff0c;并能进行语音告警播放。硬件支持RTSP、GB28181协议、以及厂家私有协议接入&#xff0c;可兼容市面上常见的…