Linux-3 进程概念(三)

1.环境变量

1.1基本概念

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

环境变量彼此之间其实没有关系,一般是具有特殊用途的变量                                                       定义变量的本质,其实是开辟空间;在运行期间我们的程序也能开辟空间                                     操作系统/bash是用C语言写的程序,也可以在运行中开辟空间

1.2常见的环境变量

env 可以查看系统环境变量

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

1.3和环境变量相关的命令

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

set 可以查到几乎所有的变量 

当 PATH 的内容被覆盖之后 XShell断开登陆重新连接后 PATH又回到了默认了

登陆系统时,环境变量从磁盘中来(脚本或某些配置文件夹) 系统启动后环境变量从磁盘->内存 

所有的环境变量都是内存级的,在进程(bash)的上下文当中的                                                          当bash进程退出,环境变量自然就没了

1.4环境变量PATH

$PATH: 

 当我们 ls 显示当前路径文件时,和运行自己写的代码时,有没有想过:                                         为什么我们的代码运行要带路径,而系统的指令不用带路径?                                                           如果我们直接输入我们的可执行程序,会显示 bash: process: command not found

可以用echo查看PATH环境变量

 为什么系统命令(程序)“不用”绝对路径就能执行?                                                                           系统在环境变量PATH默认路径找,系统命令都能找到

 那么如何让自己的程序不用绝对路径就能用呢?                                                                               1.拷到默认搜索路径下(这就相当于把软件安装到系统里)                                                                   2.把程序所属路径添加到默认搜索路径下

pwd查看当前路径,把当前路径添加到环境变量中:export PATH=$PATH:路径

1.5获取环境变量

main函数有3个参数

前两个参数叫作命令行参数,第三个叫作环境变量参数。

  • 第一个参数:int argc是个整型变量,表示命令行参数的个数(含第一个参数)。
  • 第二个参数:char *argv[ ]是个存放字符指针的数组,每一个元素一个字符指针,指向一个字符串。这些字符串就是命令行中的每一个参数(字符串)。
  • 第三个参数:char *envp[ ]也是存放字符指针的数组,数组的每一个原元素是一个指向一个环境变量(字符串)的字符指针。
#include <stdio.h>    
#include <unistd.h>    
#include<stdlib.h>    int main(int argc,char *argv[],char *env[])    
{    for(int i=0;env[i];i++)    {    printf("-----------env[%d]->%s\n",i,env[i]);                                                                                                                                                                }    return 0;    
}    

环境变量是当你 进入系统这个环境给你准备的变量

bash进程创建子进程时会帮我们维护两张表:命令行参数表、环境变量表(environ)

而这个表就是我们main函数的第三给参数char* env[]指向的表,环境变量可以被子进程继承下去

还可以用第三方变量environ获取

另外还能直接通过变量名获取环境变量

 

 2.进程地址空间

2.1引入

怎么理解这张图呢?

我们来验证一下

#include <stdio.h>    
#include <unistd.h>    
#include <stdlib.h>    int g_unval;    
int g_val = 100;                                         
int main()                                               
{                                                        printf("code addr:%p\n",main);                         printf("init data addr:%p\n",&g_val);//已初始          printf("uninit data addr:%p\n");                          char *heap = (char*)malloc(20);                           printf("heap addr:%p\n",heap);//堆                        printf("stack addr:%p\n",&heap);//栈                      return 0;                                      
}   

已初始化数据和未初始化数据会在进程运行期间一直存在

#include <stdio.h>    
#include <unistd.h>    
#include <stdlib.h>    int main()    
{      char *heap1 = (char*)malloc(20);    char *heap2 = (char*)malloc(20);    char *heap3 = (char*)malloc(20);    printf("heap1 addr:%p\n",heap1);//堆    printf("heap2 addr:%p\n",heap2);    printf("heap3 addr:%p\n",heap3);    printf("stack1 addr:%p\n",&heap1);//栈    printf("stack2 addr:%p\n",&heap2);    printf("stack3 addr:%p\n",&heap3);                                                                                                                                                                              return 0;    
}  

 可以看出堆向上增长     栈向下增长

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
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{ //parentsleep(3);printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);}sleep(1);return 0;
}

可以发现值不一样但是地址却是一样的   那么这个地址不可能是物理地址

我们所用到的所有的地址全都不是物理地址

所以刚才那个内存不是物理内存,叫进程地址空间

平时在用时访问的是地址空间的地址(虚拟内存),最终的数据是一定要存到物理内存当中的

那么地址空间怎么找到内存中的值呢?

引入一个区域划分的概念

为什么要进行区域划分?1.可以判断是否越界;2可以进行扩大或者缩小范围

区域划分的本质就是:区域内的各个地址都可以使用

可是我们的地址空间不具备对我们的代码和数据的保存能力,需要在物理内存中存放

需将地址空间上的(虚拟/线性)地址转化到物理内存中,系统给我们的进程提供一张映射表——页表

 

 回到刚才值不一样地址一样的问题:

每个进程都有task_struct、进程地址空间、映射关系,子进程也要有,而且子进程会继承父进程的地址空间、大部分属性、映射关系,所以会指向同一地址

那么值不一样是怎么修改的呢?因为进程是有独立性的(不能直接修改,会影响父进程)

子进程的值不一样改的是映射关系,同样的虚拟地址映射关系不同,那么指向的物理内存就不同     在物理内存重新开辟一块空间,修改映射关系指向这块空间

之前我们用id进行分流(为父/子进程)怎么可能一个id既大于0又等于0,就是同一个虚拟内存映射到不同的物理内存

2.2什么是进程地址空间

进程地址空间是指每个进程在计算机内存中所占用的地址空间。地址空间是指能被访问的内存地址 范围,它由若干个连续的内存块组成。每个进程都有自己的地址空间,这意味着每个进程都有自己 的内存地址范围,不会与其他进程冲突

系统给每个进程划分了很大的一块虚拟空间,所有的进程都认为自己会独占系统资源(实际上,这只是操作系统给进程画的饼)。等到进程真正申请的资源和空间的时候系统再到物理内存分配空间给进程

既然进程地址空间是一张”饼“,那么”饼“要管理吗?OS要不要堆地址空间做管理呢?自然是要的

怎么管理?先描述,再组织

所以进程地址空间的本质就是数据结构,具体到进程中就是特定数据结构的对象

2.3为什么要有地址空间+页表

地址空间:

1.进程地址空间会识别不安全的命令,并拒绝,可以阻止地址非法访问

2.通过页表将物理内存从无序变有序,让进程以统一的视角看内存(比如:正文区域,在物理内存申请的空间是一块一块的,通过页表可以把它们集中在正文区域)

3.进程地址空间的存在,可以更方便的进行进程和进程的数据代码之间的解耦合(减少模块与模块直接的关联性,以前说过开发要尽量:低耦合,高内聚)保证了进程的独立性

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

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

相关文章

初识Solidworks:我的第一份作业的感想

从来没用CAD软件画过机械设计图。但我脑子里有一种概念&#xff0c;无非就是把尺规作图软件化&#xff0c;更方便画图、更方便修改、更方便打印一些。但第一份 Solidworks 作业就颠覆了我的认知&#xff0c;考虑到这个软件的上市时间&#xff0c;让我意识到自己对 CAD 软件的认…

如何让内网client通过公网地址访问内网server?

第一步&#xff0c;实现任意公网用户访问内网server。按教育网规矩&#xff0c;公网过来的流量要访问校内网的server必须从教育专线&#xff08;路由器接口G0/0/1)进入。 第二步&#xff0c;实现内网主机通过公网地址210.43.2.3能够访问内网server192.168.1.2&#xff0c;图中①…

ES实战-book笔记1

#索引一个文档,-XPUT手动创建索引, curl -XPUT localhost:9200/get-together/_doc/1?pretty -H Content-Type: application/json -d {"name": "Elasticsearch Denver","organizer": "Lee" } #返回结果 {"_index" : "g…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Toggle组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之Toggle组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Toggle组件 组件提供勾选框样式、状态按钮样式及开关样式。 子组件 仅当Toggl…

林浩然与杨凌芸的Java异常处理大冒险

林浩然与杨凌芸的Java异常处理大冒险 Lin Haoran and Yang Lingyun’s Java Exception Handling Adventure 在一个阳光明媚的午后&#xff0c;编程世界的英雄——林浩然和杨凌芸坐在Java王国的咖啡馆里&#xff0c;一边品尝着香醇的代码咖啡&#xff0c;一边探讨着他们的最新挑…

干掉Xshell,这款开源的终端工具逼格真高!

GitHub 上已经有 53.7k 的 star 了&#xff0c;这说明 Tabby 非常的受欢迎&#xff1a; https://github.com/eugeny/tabby Tabby 是一个高度可定制化的 跨平台的终端工具&#xff0c;支持 Windows、macOS 和 Linux&#xff0c;自带 SFTP 功能&#xff0c;能与 Linux 服务器轻…

Blazor入门100天 : 自做一个支持长按事件的按钮组件

好长时间没继续写这个系列博客了, 不知道大家还记得我吗? 话不多说,直接开撸. 配套源码 demo https://blazor.app1.es/b19LongPressButton ####1. 新建 net8 blazor 工程 b19LongPressButton 至于用什么模式大家各取所需, 我创建的是ssr单工程, 如果大家不小心建立错了按页…

Mysql——更新数据

注&#xff1a;文章参考&#xff1a; MySQL 更新数据 不同条件(批量)更新不同值_update批量更新同一列不同值-CSDN博客文章浏览阅读2w次&#xff0c;点赞20次&#xff0c;收藏70次。一般在更新时会遇到以下场景&#xff1a;1.全部更新&#xff1b;2.根据条件更新字段中的某部分…

[office] excel求乘积的公式和方法 #媒体#笔记#经验分享

excel求乘积的公式和方法 本文首先给出两个常规的excel求乘积的链接&#xff0c;然后再例举了一个文字和数字在同一单元格里面的excel求乘积的公式写法。 excel求乘积的方法分为两种&#xff0c;第一种是直接用四则运算的*来求乘积&#xff0c;另外一种就是使用PRODUCT乘积函数…

【51单片机】自定义静态数码管显示(设计思路&代码演示)

前言 大家好吖&#xff0c;欢迎来到 YY 滴单片机系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过单片机的老铁 主要内容含&#xff1a; 本章节内容为【实现动静态数码管】项目的第三个模块完整章节&#xff1a;传送门 欢迎订阅 YY滴C专栏&#xff01;更多干货持…

谷歌发布AI新品Gemini及收费模式;宜家推出基于GPT的AI家装助手

&#x1f989; AI新闻 &#x1f680; 谷歌发布AI新品Gemini及收费模式 摘要&#xff1a;谷歌宣布将原有的AI产品Bard更名为Gemini&#xff0c;开启了谷歌的AI新篇章。同时推出了强化版的聊天机器人Gemini Advanced&#xff0c;支持更复杂的任务处理&#xff0c;提供了两个月的…

springboot175图书管理系统

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

Netty应用(二) 之 ByteBuffer

目录 4.ByteBuffer详解 4.1 ByteBuffer为什么做成一个抽象类&#xff1f; 4.2 ByteBuffer是抽象类&#xff0c;他的主要实现类为 4.3 ByteBuffer的获取方式 4.4 核心结构&#xff08;NIO的ByteBuffer底层是啥结构&#xff0c;以及读写模式都是根据这些核心结构进行维护的&a…

Netty应用(一) 之 NIO概念 基本编程

目录 第一章 概念引入 1.分布式概念引入 第二章 Netty基础 - NIO 1.引言 1.1 什么是Netty&#xff1f; 1.2 为什么要学习Netty&#xff1f; 2.NIO编程 2.1 传统网络通信中开发方式及问题&#xff08;BIO&#xff09; 2.1.1 多线程版网络编程 2.1.2 线程池版的网络编程…

渗透测试-信息打点与架构分析细节梳理

渗透测试-信息打点与架构分析细节梳理 为了保障信息安全&#xff0c;我在正文中会去除除靶场环境的其他任何可能的敏感信息 什么是网站架构 网站架构包括网站的方方面面&#xff0c;下面是常见的内容&#xff1a; 前端&#xff08;Front-End&#xff09;&#xff1a; 使用Reac…

【C语言】深入理解指针

目录 1.字符指针 2.指针数组 3.数组指针 4.数组传参与指针传参 一维数组传参 二维数组传参 一级指针传参 二级指针传参 5.函数指针 6.函数指针数组 7.指向函数指针数组的指针&#xff08;了解即可&#xff09; 8.回调函数 回调函数的应用&#xff1a;库函数qsort …

ANSI Escape Sequence 下落的方块

ANSI Escape Sequence 下落的方块 1. ANSI Escape 的用途 无意中发现 B站有人讲解&#xff0c; 完全基于终端实现俄罗斯方块。 基本想法是借助于 ANSI Escape Sequence 实现方方块的绘制、 下落动态效果等。对于只了解 ansi escape sequence 用于 log 的颜色打印的人来说&…

webgis后端安卓系统部署攻略

目录 前言 一、将后端项目编译ARM64 二、安卓手机安装termux 1.更换为国内源 2.安装ssh远程访问 3.安装文件远程访问 三、安装postgis数据库 1.安装数据库 2.数据库配置 3.数据导入 四、后端项目部署 五、自启动设置 总结 前言 因为之前一直做的H5APP开发&#xf…

春节特辑 | 催婚大作战与奇妙相亲记

点击文末“阅读原文”即可参与节目互动 剪辑、音频 / 卷圈 运营 / SandLiu 卷圈 监制 / 姝琦 封面 / 姝琦Midjourney 产品统筹 / bobo 场地支持 / 声湃轩天津录音间 催催催&#xff0c;一到春节&#xff0c;七大姑八大姨都来纷纷关心“怎么样了&#xff1f;还单着呢&…

C++类和对象(7)

目录 3. 友元 3.1 友元函数 3.2 友元类 4. 内部类 5.匿名对象 6.拷贝对象时的一些编译器优化 7. 再次理解类和对象 3. 友元 友元提供了一种突破封装的方式&#xff0c;有时提供了便利。但是友元会增加耦合度&#xff0c;破坏了封装&#xff0c;所以 友元不宜多用。 友元…