【Linux】进程的地址空间

一、看现象


  1 #include<stdio.h>
  2 #include<unistd.h>
  3 
  4 int g_val = 100;
  5 int main()
  6 {
  7   printf("father process is running!pid: %d,ppid: %d\n",getpid(),getppid(    ));
  8   sleep(1);
  9 
 10   int id = fork();
 11   if(id == 0)
 12   {
 13     int cnt = 0;
 14     while(1)
 15     {
 16       printf("This is child process.pid: %d,ppid: %d,g_val: %d,&g_val: %p    \n",getpid(),getppid(),g_val,&g_val);
 17       sleep(1);
 18       cnt++;
 19       if(cnt == 5)
 20       {                                                                  
 21         g_val = 200;
 22         printf("This is child process.chang %d -> %d\n",100,200);
 23       }
 24     }
 25   }
26   else 
 27   {
 28     while(1)
 29     {
 30       printf("This is father process.pid: %d,ppid: %d,g_val: %d,&g_val: %    p\n",getpid(),getppid(),g_val,&g_val);
 31       sleep(1);
 32     }
 33  }
 34 }

运行以上代码,结果如下

可以看出,起初子进程和父进程都认为g_val值为100,且g_val地址相同,但当一段时间后子进程修改g_val的值后,子进程检测到的g_val值确实是修改后的值,但是父进程检测到的g_val确实修改前的值。这种现象体现出父子进程对数据的处理,我们知道父子进程是具有独立性的。

进程=内核数据结构(task_struct)+代码和数据,所以每个进程都应该有自己独立的内核数据结构和代码与数据。我们知道代码是只读的,子进程会继承父进程的数据,但是数据应该是可以修改的,那子进程修改数据不应该影响父进程的数据,所以子进程和父进程的g_val不能是同一个变量。可是为什么&g_val是相同的呢?说明这个地址绝对不是物理地址,我们称其为虚拟地址!!

二、快速理解

在32位平台下,程序的地址空间大小为1G

        每个进程都要有自己独立的地址空间及页表,操作系统如何管理地址空间呢?实际上地址空间的本质就是内核中的一个结构体对象,父进程创建子进程时子进程的地址空间会继承父进程地址空间的内容,其中包含了虚拟地址,所以父子进程的虚拟地址是相同的。当发生写入操作时,操作系统会在内存中开辟一块空间并修改子进程中页表的内容,再将修改的值写入该空间,即发生写时拷贝。

        为什么会有上述情况发生?因为进程具有独立性,多进程运行,需要独享各种资源,多进程运行期间互不干扰。

        如果父子进程不执行写操作,未来一个全局变量,默认是被父子共享的,代码也是共享的(只读的)。要修改的时候还要等待执行浅拷贝的时间,那么我们能不能把数据在创建子进程的时候,直接全部给子进程拷贝一份呢?这种行为是不建议的,因为进程内的数据量很大,并且也不是所有的数据都需要修改,更加浪费空间与时间。所以我们在有写操作时再申请空间更加高效,通过调整拷贝的时间顺序,从而达到有效节省空间的目的。

三、深入理解

1.如何理解地址空间

地址空间本质是内核的一个struct结构体,内部很多的属性都是表示start、end范围

源代码中struct mm_struct部分内容如下

2.为什么要有地址空间

将无序变成有序,让进程以统一的视角看待物理内存以及自己运行的各个区域。在没有地址空间前,进程的代码和数据在内存中的存储可能并不是连续的,这样进程PCB必须记录下其起始地址范围,极其麻烦。 而引入地址空间后,有划分好的代码区、数据区等,进程信息就被存在特定的位置。

进程管理模块和内存管理模块进行解耦。当申请了一些堆空间,同时并将物理内存给它,但如果不及时使用,会造成浪费,降低效率。当引入地址空间后,我们先为它开辟地址空间,但先不开辟物理内存,即不通过页表建立映射关系,等到需要的时候再开辟内存,这样内存的使用率也就变得非常高了。

 拦截非法请求,对物理内存进行保护。当发生越界访问时,所使用的虚拟地址在页表中并不能找到,没有对于的映射关系,此时操作系统就会拦截这次的访问请求,避免了在物理内存中写入数据而影响其他数据。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue快速入门(三十二)局部与全局注册组件的步骤

注释很详细&#xff0c;直接上代码 上一篇 新增内容 局部注册组件全局注册组件 文件结构 源码 MyHeader.vue <!-- 用于测试全局注册组件 --> <template><div><h1>又可以愉快的学习啦</h1></div> </template><script>export d…

go语言并发实战——日志收集系统(四) 利用tail包实现对日志文件的实时监控

Linux中的tail命令 tail 命令是一个在 Unix/Linux 操作系统上用来显示文件末尾内容的命令。它可以显示文件的最后几行内容&#xff0c;默认情况下显示文件的最后 10 行。tail 命令 非常有用&#xff0c;特别是在我们查看日志文件或者监视文件变化时。 基本用法如下&#xff1a…

LLM生成模型在生物单细胞single cell的应用:scGPT

参考&#xff1a; https://github.com/bowang-lab/scGPT https://www.youtube.com/watch?vXhwYlgEeQAs 相关算法&#xff1a; 主要是把单细胞测序出来的基因表达量的拼接起来构建成的序列&#xff0c;这里不是用的基因的ATCG&#xff0c;是直接用的基因名称 训练数据&#x…

vue+springboot+websocket实时聊天通讯功能

前言 在我的前一篇文章里 vuespringboot实现聊天功能 &#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388; 实现了最最基础的聊天功能&#xff0c;可以通过聊天互相给对方发送信息 &#x1f388;&#x1f388;&#x1f388;&…

Python全栈开发前端与后端的完美融合

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在当今互联网时代&#xff0c;全栈开发已经成为了一种趋势。全栈开发者具备前端和后端开发的…

KMP算法(Python)

进阶的做法就是KMP算法&#xff0c;当然暴力也能ac。 KMP主要用一个nex列表&#xff0c;nex[i]存储&#xff08;模式串needle中&#xff09;从第0个到i个字符串s中的一个相等前后缀的最大长度。比如说对于aabaa来说&#xff0c;最大长度应该是&#xff08;前缀aa&#xff09;和…

HarmonyOS开发案例:【首选项】

介绍 本篇Codelab是基于HarmonyOS的首选项能力实现的一个简单示例。实现如下功能&#xff1a; 创建首选项数据文件。将用户输入的水果名称和数量&#xff0c;写入到首选项数据库。读取首选项数据库中的数据。删除首选项数据文件。 最终效果图如下&#xff1a; 相关概念 [首…

盗梦攻击:虚拟现实系统中的沉浸式劫持

虚拟现实&#xff08;VR&#xff09;硬件和软件的最新进展将改变我们与世界和彼此互动的方式&#xff0c;VR头显有可能为用户提供几乎与现实无差别的深度沉浸式体验。它们还可以作为一种跨越遥远距离的方式&#xff0c;通过使用个性化的化身或我们的数字代表&#xff0c;促进社…

笔记-----BFS宽度优先搜索

对于BFS&#xff1a;宽搜第一次搜到就是最小值&#xff0c;并且基于迭代&#xff0c;不会爆栈。 Flood Fill 模型 如果直译的话就是&#xff1a;洪水覆盖&#xff0c;意思就是像是从一个点一圈圈的往外扩散&#xff0c;如果遇见能够连通的就扩散&#xff0c;如果遇见无法联通的…

汽车4S集团数据分析

派可数据分析--汽车4S集团。 派可数据汽车4S集团数据分析概述。派可数据汽车4S集团分析主题全面涵盖行业内各板块业务分析&#xff0c;具体包括&#xff1a;保险业务分析、客户关系分析、汽车保养情况分析、售后维修主题分析、整车销售分析、整车库存分析、装具销售分析、配件…

原型和原型链--图解

https://juejin.cn/post/7255605810453217335 prototype是函数的属性&#xff08;一个对象&#xff09;&#xff0c;不是对象的属性&#xff0c;普通函数和构造函数的prototype属性是空对象&#xff5b;&#xff5d;&#xff08;其实有2个属性&#xff0c;一个是constructor&a…

账号安全基本措施2

sudo命令 sudo(superuser do)&#xff0c;允许系统管理员让普通用户执行一些或者全部的root命令的一个工具。 其配置在/etc/sudoers权。它允许系统管理员集中的管理用户的使用权限和使用的主机。属性必须为0440。 语法检查&#xff1a; 检查语法&#xff1a; 修改文件时&…

Excel中将单元格格式改成文本后,为何要双击数字才会改变?

将大批量的数值型数字转换成文本型数字&#xff0c;当然不能一个一个的去双击做转换了。以下说说有哪个可以将数值型数字转换成文本型数字的方法。 一、转换方法 方法1.数据分列功能 选中数据后&#xff0c;点击数据选项卡&#xff0c;分列&#xff0c; 分列向导的第一步和…

部署轻量级Gitea替代GitLab进行版本控制(一)

Gitea 是一款使用 Golang 编写的可自运营的代码管理工具。 Gitea Official Website gitea: Gitea的首要目标是创建一个极易安装&#xff0c;运行非常快速&#xff0c;安装和使用体验良好的自建 Git 服务。我们采用Go作为后端语言&#xff0c;这使我们只要生成一个可执行程序即…

ACL的基本配置

已经启用&#xff52;&#xff49;&#xff50;实现了全网可达。 这时我们要拒绝R1与R4的路由通信&#xff0c;做标准ACL过滤关注源IP需要尽量靠近目标。则在R4的物理接口G0/0/1的&#xff49;&#xff4e;接口上做&#xff0c;不能在R4的环回接口上做&#xff0c;因为ACL列表…

【Taro3踩坑日记】找不到sass的类型定义文件

问题截图如下&#xff1a;找不到sass的类型定义文件 解决办法&#xff1a; 1、npm i types/sass1.43.1 2、然后配置 TypeScript 编译选项&#xff1a;确保 TypeScript 编译器能够识别 Sass 文件&#xff0c;并正确处理它们。

小程序 前端如何用wx.request获取 access_token接口调用凭据

在微信小程序中&#xff0c;获取access_token通常是通过wx.request方法来实现的。以下是一个简单的示例代码&#xff1a; 1.获取小程序的appID 与 secret&#xff08;小程序密钥&#xff09; 登录之后,请点击左侧的"开发管理">点击"开发设置" 就可以找…

在Ubuntu 22.04上安装配置VNC实现可视化

前面安装的部分可以看我这篇文章 在Ubuntu 18.04上安装配置VNC实现Spinach测试可视化_ubuntu18开vnc-CSDN博客 命令差不多一样&#xff1a; sudo apt update sudo apt install xfce4 xfce4-goodies sudo apt install tightvncserver这个时候就可以启动server了 启动server&…

.net8系列-01手把手教你创建一个新的.net应用(.net7和.net8的不同点)以及三种方案进行接口调试

前提条件 如果没有安装VS2022.17.8 版本环境&#xff0c;请参考我的.net系列其他安装步骤文章来进行安装&#xff08;发布本文的时候另一篇文章正在审核无法放链接&#xff0c;等后续补充哦&#xff0c;也可以自己搜索我的博文哦~很齐全&#xff09; Windows版本.net环境搭建…

iOS -- 工厂设计模式

iOS -- 工厂设计模式 设计模式概念设计模式七大准则简单工厂模式优点缺点主要作用示例 工厂方法模式优点缺点主要作用&#xff1a; 抽象工厂方法缺点主要作用&#xff1a;文件分类 设计模式概念 所谓设计模式&#xff08;Design pattern&#xff09; 是解决软件开发某些特定问…
最新文章