Linux进程概念(续)

news/2024/7/5 4:18:09


引入

我们先来看一段代码

#include<stdio.h>
#include <unistd.h>

int g_val=200;//全局变量
int main()
{
    int res=fork();
    if(res>0)//father
    {
        printf("我是父进程。我的全局变量 g_val=%d,他的地址是 %p\n",g_val,&g_val);
    }
    else if(res==0)//子进程
    {
        g_val=100;
          printf("我是子进程。我的全局变量 g_val=%d,他的地址是 %p\n",g_val,&g_val);
    }
    else{
        printf("出错啦");
        return -1;
    }
    return 0;
}

结果可能让人很,,,无措

 

 同一个地址怎么会存储不同的值呢?

答案是

这里的地址,绝对不是物理内存的地址!! ! ! ! ! ! ! ! ! ! ! !!
不是物理地址,而是:虚拟地址(线性地址)!
几乎所有的语言,如果他有“地址”的概念,这个地址一定不是物理地址,而是虚拟地址!! !

进程地址空间

什么是地址空间

1.验证地址空间的排布

  • 代码演示

#include<stdlib.h>
#include<stdio.h>

int g_val=10;
int g_uval;
int main(int argc,char* argv[],char* envp[])
{
    printf("代码区:%p\n",main);
    char* str="abcde";
    printf("只读常量区: %p\n",str);
    printf("初始化数据区: %p\n",&g_val);
    printf("未初始化数据区: %p\n",&g_uval);

    int *p=(int*)malloc(10);
    printf("堆区: %p\n",p);
    printf("栈区: %p\n",&p);
    printf("###############\n");
    int i=0;
    for(i=0;i<argc;i++)
    {
        printf("命令行参数:%p\n",argv[i]);
    }

    while(envp[i])
    {
        printf("环境变量: %p\n",&envp[i]);
        i++;
    }

return 0;
}
  • 演示效果                                           对比排布

进程地址空间分为代码区,常量区,堆栈相对而生,命令行参数,环境变量

为什么要有地址空间

1.历史上过去是可以直接访问物理内存的,这种方式特别不安全。

现代计算机提出了下面的方式:

 如何理解区域划分

上小学的时候,想来有很多同学都经历过38线吧。就像这样

struct desktop{
int start;
int end;
}
struct desktop one =[1,50]
struct desktop one =[51,100]

地址空间是一种内核数据结构,它里面至少有各个区域的划分

所谓的范围变化,本质是对start或者end标记值+ - 一定的范围即可

内核中的结构体名称是mm_struct ,地址空间和页表是每个进程都私有一份,只要保证,每一个页表映射的是物理内存的不同区域,就能做到,进程之间不会相互干扰,保证进程的独立性。

所以,开头的同一个地址存放不同的值也能理解了.

当我们的程序,在编译的时候,形成可执行程序的时候,没有被加载到内存中的时候,

请问:我们程序内部,有地址吗??
其实已经有地址了! ! !
可执行程序其实编译的时候,内部已经有地址了!
地址空间不要仅仅理解成为是OS内部要遵守的,其实编译器也要遵守!!!,即编译器编译代码的时候,就已经给我们形成了各个区域代码区,数据区,...并且,采用和Linux内核中一样的编址方式,给每一个变量,每一行代码都进行了编址,故,程序在编译的时候,每一个字段早已经具有了一个虚拟地址! ! !

程序内部的地址,依旧用的是编译器编译好的虚拟地址
当程序加载到内存的时候,每行代码,每个变量边具有了一个物理地址,外部的

2.凡是非法的访问或者映射,0S都会识别到,并终止你这个进程!!!
有效的保护了物理内存吗! !
 

因为地址空间和页表是0S创建
并维护的!是不是也就意味着
凡是想使用地址空间和页表进行
映射,也--定要在OS的监管之下又
来进行访问! !
也便保护了物理内存
中的所有的合法数据
包括各个进程,以及内核的相关有效数据!

 

 3.

1)因为在物理内存中理论上可以任意位置加载,那么是不是物理内存中的几乎所有的数据和代码在内存中是乱序的呢?
2)但是,因为页表的存在,它可以将地址空间上的虚拟
地址和物理地址进行映射,那么是不是在进程视角所有的内存分布,都可以是有序的! !

3)地址空间+页表的存在可以将内存分布,有序化!

4)地址空间是0S给进程画的大饼

5)结合第2条:进程要访问的物理内存中的数据和代码,可能目前并没有在物理内存中,同样的,也可以让不同的进程映射到不同的物理内存,是不是很容易做到

6)进程的独立性,可以通过地址空间+页表的实现!

结论:
因为有地址空间的存在,每-一个进程都认为自己拥有4GB空间(32),并且各个区域是有序的,进而可以通过页表映射到不同的区域,来实现进程的独立性! !


http://lihuaxi.xjx100.cn/news/1375201.html

相关文章

servicemanager的启动流程

servicemanager进程的入口 在frameworks/native/cmds/servicemanager/Android.bp文件中 cc_binary {name: "servicemanager",defaults: ["servicemanager_defaults"],init_rc: ["servicemanager.rc"],srcs: ["main.cpp"], }cc_binar…

五,Eureka 第五章

5.3.2 修改pom添加依赖 <dependencies><!--公共部门--><dependency><groupId>cn.bdqn</groupId><artifactId>springcloud-api-commons</artifactId><version>${project.version}</version></dependency><!--e…

java中的动态代理机制

目录 什么是动态代理&#xff1f; 为什么需要代理&#xff1f; 代理长什么样子&#xff1f; 代码样例 什么是动态代理&#xff1f; 动态代理可以无侵入式的给代码增加功能 为什么需要代理&#xff1f; 对象如果嫌弃身上的事情太多&#xff0c;就可以通过代理来转移部分的…

解决Cannot resolve plugin org.apache.maven.plugins:xxxxxxxx

解决Cannot resolve plugin org.apache.maven.plugins:xxxxxxxx 方法一、检查配置设置 下图中三个方框圈出来的地方设置为自己的下载的maven地址&#xff0c;配置文件地址&#xff0c;仓库地址。刷新maven。 我个人试过没用&#xff0c;不过网上有的朋友用这个方法解决了。 …

c++解析 一行字符串输入、 java大整数模板

nums [1,3,-1,-3,5,3,6,7], k 3将上述输入转换为c的输入 vector<int> split(const string& str, char sep) {vector<int> tokens;int i;stringstream ss(str);while (ss >> i) {tokens.push_back(i);if (ss.peek() sep) {ss.ignore();}}return tokens…

ROS noetic,ROS melodic 安装 MoveIt 并运行

ROS noetic&#xff0c;ROS melodic 安装 MoveIt 并运行 前言更新功能包版本下载依赖文件创建工作区和软件源下载源代码安装编译器缓存&#xff08;可选环节&#xff09;编译Moveit&#xff01;安装Moveit&#xff01;检测是否安装成功 前言 在安装过程中我也碰壁过很多次&…

RecyclerView 一次性加载大量数据时(2000条音频数据),导致UI线程卡顿,频繁GC的问题

问题描述&#xff1a; 公司项目有这么一个需求&#xff0c;扫描sdCard或U盘的音频数据&#xff0c;并分类展示出来&#xff0c;当数据量比较大时&#xff08;2000多条数据以上&#xff09;&#xff0c;显示列表慢和滑动列表会很卡。 问题的寻找过程&#xff1a; 当时想的就是…

spring6——概述

文章目录 概述Spring 是什么&#xff1f;Spring 的狭义与广义Spring Framework特点Spring模块组成 概述 Spring 是什么&#xff1f; Spring 是一款主流的 Java EE 轻量级开源框架 &#xff0c;Spring 由“Spring 之父”Rod Johnson 提出并创立&#xff0c;其目的是用于简化 J…