标准网站建设报价单六安在建项目和拟建项目
news/
2025/10/5 15:31:44/
文章来源:
标准网站建设报价单,六安在建项目和拟建项目,广东外贸网站建设,wordpress安装配置php5.2#x1f44d;作者主页#xff1a;进击的1 #x1f929; 专栏链接#xff1a;【1的Linux】 文章目录 一#xff0c;什么是进程地址空间#xff1f;二#xff0c;进程地址空间是怎么设计的#xff1f;三#xff0c;为什么要有进程地址空间#xff1f; 一#xff0c;什… 作者主页进击的1 专栏链接【1的Linux】 文章目录 一什么是进程地址空间二进程地址空间是怎么设计的三为什么要有进程地址空间 一什么是进程地址空间
我们先来看一幅图 这就是我们的进程地址空间的分布。 其分为了内核空间和用户空间。从具体进程的角度来看每个进程可以拥有4G字节的虚拟地址空间(也叫虚拟内存)。其中每个进程有各自的私有用户空间03G这个空间对系统中的其他进程是不可见的。最高的1GB内核空间则为所有进程以及内核所共享。 而用户空间又被细分为我们所熟知的堆区栈区代码区… 接下来我们对用户空间的分布进行验证
#includestdio.h
#includestdlib.h
int global3;
int uninit_global;
int main()
{printf(正文代码%p\n,main);printf(初始化数据%p\n,global);printf(未初始化数据%p\n,uninit_global);int* ptr(int*)malloc(sizeof(int));printf(堆区%p\n,ptr);printf(栈区%p\n,ptr);return 0;
}
运行结果 由此我们可以基本得出我们所谓的数据在进程地址空间中就是那样分布的。 还需要补充的就是堆栈相对而生static修饰的变量本质是将其开辟在全局区域。
在来一个有意思的小实验: 代码如下
#includestdio.h
#includeunistd.hint global0;
int main()
{size_t retfork();if(ret0){perror(进程错误);}else if(ret0){global3;printf(child::pid:%d---global:%d---address:%p\n,getpid(),global,global);sleep(1);}else{printf(father::pid:%d---global:%d---address:%p\n,getpid(),global,global);}return 0;
} 我们观察结果可以发现全局变量global在父子进程的值不一样但是其地址却是相同的。 我们可以得出 其首先变量的内容内容不同其肯定不是同一个变量。 然后不同变量但地址却相同其肯定不是物理地址。 那是什么呢 这就是虚拟地址—也就是我们今天要将的进程地址空间。 我们编写代码时所说的地址都是虚拟地址。而我们的数据都是通过虚拟地址—页表—物理地址 这样的映射关系与物理内存产生联系的。如下图-----同一个变量地址相同其实是虚拟地址相同内容不同其实是被映射到了不同的物理地址我们在后面会对这部分做出详细的说明。
二进程地址空间是怎么设计的
地址空间本质是一种数据结构其里面至少要有各个区域的划分将来要和一个特定的进程相关联。也就是说每一个进程都会有一个地址空间因此也就有了上述例子中地址相同的情况。 区域划分本质就是在一个范围里定义start和end。 我们的程序在编译时编译器就形成了地址空间中的各个区域并且采用和内核中一样的编址方式给每一行代码每一个变量都进行了编制。所以在程序编译时每一个字段就已经有了虚拟地址。只有当程序加载到内存中其才会有物理地址。
地址空间页表最开始的数据则是由磁盘给的。
那么操作系统是如何管理地址空间的呢 我们直到OS是通过PCB来管理进程的每个进程都有一个独立的地址空间我们前面一直提到的管理方式先描述后组织。对于地址空间的管理也是一样的我们将其组织成为一种数据结构在PCB中会有一个指向地址空间的指针mm_struct。OS通过这个指针就可以间接的对进程的地址空间进行管理。
三为什么要有进程地址空间
原因一 对于物理内存来它是可以任意进行读写的因此若没有地址空间用户直接对内存进行操作则会引起安全问题。凡是非法的访问或映射OS都会识别到并且终止掉这个进程也就是说所有的进程奔溃就是进程的退出地址空间和页表是由OS创建的所以凡是想要通过地址空间和页表进行映射都要在OS的监控下那么就保护了物理内存中的数据的安全。
原因二 因为有了地址空间我们的物理内存和进程之间就可以分开管理完成解耦合。 我们在编程时所说的申请空间new,malloc都是在地址空间中申请所以我们采用延迟分配的策略来提高效率只有我们的程序真正对物理内存进行访问时才会给你申请物理内存。也就是说使用地址空间可以提高整机效率。
原因三 物理内存在理论上可以在任意位置加载那么在物理内存中的所有数据和代码也都是混乱的。 有了页表的存在可以将虚拟地址和物理地址之间进行映射那么在进程视角内存分布就时有序化的。因为由地址空间和页表的存在每个进程都认为自己拥有全部的空间并且各个区域是有序的通过页表映射到物理内存不同的区域实现进程的独立性。
补充知识
什么是挂起 加载的本质就是创建进程但创建好的进程不是必须把代码和数据马上加载到内存中并创建内核数据结构task_struct。在极端情况下可能只有内核结构被创建出来了。因此理论上可以对程序进行分批加载。既然可以分批加载那么就可以分批换出—当一个进程短时间不再执行----例如阻塞那么其数据和代码就会被换出这就叫做挂起。页表在映射时不仅仅能映射内存磁盘也可以进行映射。读时共享即不涉及写操作时子进程并不会复制父进程的地址空间而是和父进程共享一块地址空间。写时拷贝父进程执行部分和子进程执行部分都会对某一变量进行操作但是父进程和子进程对这个变量的操作是独立的、互不相干的此时便需要子进程复制父进程的地址空间然后父、子进程在各自空间中对这个变量进行操作。这样做可以提高内存的使用效率。父进程和子进程在执行的过程中是交替执行的执行的先后顺序是不确定的当一方的时间片执行结束后便会执行另一方。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/928413.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!