当前位置: 首页 > news >正文

营销网站建设报价付费查看wordpress

营销网站建设报价,付费查看wordpress,网站建设ppt百度文库,怎么塔建网站前言&#xff1a; 上文我们讲到了Linux中的环境变量【Linux】环境变量-CSDN博客 本文我们来讲一下Linux中的虚拟地址空间 初识空间分布 下面是虚拟地址空间的大致分布图&#xff1a; 我们可以先通过代码来验证是否正确&#xff1a; #include <stdio.h> #include <std…

前言:

        上文我们讲到了Linux中的环境变量【Linux】环境变量-CSDN博客

        本文我们来讲一下Linux中的虚拟地址空间

 初识空间分布

        下面是虚拟地址空间的大致分布图:

 

        我们可以先通过代码来验证是否正确:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int g_unval;
int g_val = 100;int main(int argc, char* argv[], char* env[])
{const char* str = "helloworld";printf("code addr: %p\n", main);printf("init global addr: %p\n", &g_val);printf("uninit global addr: %p\n", &g_unval);static int test = 10;char* heap_mem = (char*)malloc(10);char* heap_mem1 = (char*)malloc(10);char* heap_mem2 = (char*)malloc(10);char* heap_mem3 = (char*)malloc(10);printf("heap addr: %p\n", heap_mem);printf("heap addr: %p\n", heap_mem1);printf("heap addr: %p\n", heap_mem2);printf("heap addr: %p\n", heap_mem3);printf("test static addr: %p\n", &test);printf("stack addr: %p\n", &heap_mem);printf("stack addr: %p\n", &heap_mem1);printf("stack addr: %p\n", &heap_mem2);printf("stack addr: %p\n", &heap_mem3);printf("read only string addr: %p\n", str);for (int i = 0; i < argc; i++){printf("argv[%d]: %p\n", i, argv[i]);}for (int i = 0; env[i]; i++){printf("env[%d]: %p\n", i, env[i]);}return 0;
}
hyc@hcss-ecs-4ce7:~/linux/虚拟地址$ ./test
code addr: 0x55da1c103189
init global addr: 0x55da1c106010
uninit global addr: 0x55da1c10601c
heap addr: 0x55da1d1f06b0
heap addr: 0x55da1d1f06d0
heap addr: 0x55da1d1f06f0
heap addr: 0x55da1d1f0710
test static addr: 0x55da1c106014
stack addr: 0x7ffcf95ad350
stack addr: 0x7ffcf95ad358
stack addr: 0x7ffcf95ad360
stack addr: 0x7ffcf95ad368
read only string addr: 0x55da1c104004
argv[0]: 0x7ffcf95ad71f
env[0]: 0x7ffcf95ad726
env[1]: 0x7ffcf95ad736
env[2]: 0x7ffcf95ad744
env[3]: 0x7ffcf95ad75f
env[4]: 0x7ffcf95ad780
env[5]: 0x7ffcf95ad78c
env[6]: 0x7ffcf95ad7a1
env[7]: 0x7ffcf95ad7b0
env[8]: 0x7ffcf95ad7bf
env[9]: 0x7ffcf95ad7d0
env[10]: 0x7ffcf95addbf
env[11]: 0x7ffcf95addf5
env[12]: 0x7ffcf95ade17
env[13]: 0x7ffcf95ade2e
env[14]: 0x7ffcf95ade39
env[15]: 0x7ffcf95ade59
env[16]: 0x7ffcf95ade62
env[17]: 0x7ffcf95ade6a
env[18]: 0x7ffcf95ade7e
env[19]: 0x7ffcf95ade9a
env[20]: 0x7ffcf95adebe
env[21]: 0x7ffcf95adecf
env[22]: 0x7ffcf95adf10
env[23]: 0x7ffcf95adf78
env[24]: 0x7ffcf95adfab
env[25]: 0x7ffcf95adfbe
env[26]: 0x7ffcf95adfd1
env[27]: 0x7ffcf95adfe8

虚拟地址

        打印不同进程下的相同变量的地址与值

#include <stdio.h>
#include <unistd.h>int g_val = 0;int main()
{pid_t id = fork();if (id < 0){perror("fork");return 0;}else if(id == 0){ printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);}else{printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);}sleep(1);return 0;
}

        我们可以看到父子进程的输出结果都是一样的,很好理解没有问题。

        但如果子进程对变量进行修改会发生什么?

#include <stdio.h>
#include <unistd.h>int g_val = 0;int main()
{pid_t id = fork();if (id < 0){perror("fork");return 0;}else if (id == 0){ g_val=100;printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);}else{printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);}sleep(1);return 0;
}

        这时我们就会发现输出变量的地址是一模一样的,但是变量的值却不一样!这就很奇怪了。

总结:

        相同的地址值却不一样,说明我们所打印出来的绝对不可能是真实的地址。而这就是我们说所的虚拟地址

        我们在使用C/C++看到的地址,全部都是虚拟地址!物理地址,用户一概都看不到,由OS统一管理。

        换言之,OS负责讲虚拟地址转化为物理地址

虚拟地址空间

结论一:

        1.一个进程,对应拥有一个虚拟地址空间

        2.一个进程,也对应拥有一个页表。页表的作用是建立虚拟地址与物理地址的映射关系,用于虚拟地址与物理地址的转化。

        3.虚拟地址空间单位为:1字节,既一个地址指向的空间大小为1字节。32位机器有2^32个地址,64位机器有2^64个地址。32位机器的虚拟空间大小就有4G(2^32*1字节)其中3G是用户可用空间,1G是内核空间(暂时不用管)

        如果我们创建一个子进程,我们知道子进程的task_struct是拷贝父进程的,而子进程与父进程共享代码与数据(没有新继承加载进来的情况下)这也就意味了子进程的页表映射关系与父进程一模一样

        但如果子进程要修改数据呢?会发生什么?

结论二:

        子进程修改数据会发生写时拷贝:在物理空间上重新开辟,并在页表中重新建立映射关系。注意:虚拟地址并没有改变,仅仅改变了物理地址!!!

        这也就解释了最开始的代码中,为什么明明打印出来的地址相同,但是值却不同。 

写时拷贝的意义

有的同学可以困惑,为什么不创建进程的时间直接拷贝一份呢?

1.减少了创建进程的时间

        如果创建时就直接拷贝,会增加进程创建的时间:并不会进程中每一个变量都会修改

2.减少了内存的浪费

        对于不需要修改的变量,依旧拷贝就会产生冗余数据,浪费内存空间

虚拟地址空间的本质 

mm_struct

        虚拟地址空间的本身其实就是一个结构体!(mm_struct)

        我们知道虚拟空间中有许多区域划分,而如果确定区域的位置呢?只需要知道各个区域的起始位置以及结束位置就可以了。所以mm_struct的主要成员变量是各个区域的位置信息

        想要对区域进行调整,也只需要修改对应区域的start、end即可

struct mm_struct
{unsigned long start_code,end_code;unsigned long start_data,end_data;......
}

        我们说一个进程对应一个虚拟地址空间,既对应一个mm_struct。操作系统中有多个进程,必然也有多个mm_struct。那么就如何管理的呢?

        1.当数量较少时,采用单链表管理

        2.当数量较多时,采用红黑数管理

vm_area_struct

        mm_struct中还有一重要成员:vm_area_struct(存放其指针)

        vm_area_struct用来表示一个独立的虚拟内存区域,由于每个不同的虚拟内存区域功能和内部机制都不同,因此⼀个进程使⽤多个vm_area_struct结构来分别表示不同类型的虚拟内存区域,方便进程快速访问。

为什么要有虚拟地址

1.让无序的物理地址,变为有序

2.在地址的转化过程中,可以对地址以及操作进行判定是否合法,进而保护了物理内存

        例如:char* str="abc";  *str="a",为什么会报错?因为在查找页表时被拦截了!

3.让进程管理和内存管理,进行一定程度的解耦合

        不让虚拟地址与物理地址有强相关性

补充:

        1.我们可以不加载代码和数据,只有task_struct、mm_struct、页表

        2.再次理解挂起:保留虚拟地址空间以及页表中的虚拟地址,清空页表中的物理地址,将物理地址空间唤入到磁盘的swap分区中

http://www.dtcms.com/a/568384.html

相关文章:

  • 天津网站优化公司电话未来网站建设想法
  • 动易6.8网站头怎么做电商卖东西
  • 电子商务网站建设合同wordpress临时关闭站点
  • 建设网站收取广告费用产品宣传短视频
  • 做婚纱摄影网站多少钱企业一站式网站建设
  • 网站中的ppt链接怎么做的大学生网站建设小结
  • 个人网站建设模板企业创建网站
  • 网页站点的用途做网站图
  • 响应式网站开发源码网络强国建设的未来
  • 做视频网站容易收录吗wordpress搭建方案
  • 公司找人做网站游戏推广工作怎么样
  • 做网站的技术域名会影响网站排名吗
  • 如何创建一个网站链接网站做百度竞价利于百度优化
  • app手机网站模板怎么建设电子邮箱网站
  • 企业的网站品牌推广如何禁止ip访问网站
  • 文化传媒可以做网站吗网站规划与建设 ppt
  • 大安移动网站建设网站软文推广网站
  • 招远网站制作wordpress 切换语言
  • 网站开发后端待遇如何做网站的软件
  • 做同城网站还有机会吗济南建设个人网站平台
  • 清远seo站内优化如何用ae做模板下载网站
  • 长沙网站seo技巧男科免费咨询
  • 东阳市住房和城乡建设局网站系部网站开发计划书
  • 网站无法上传图片网站模板 电器
  • 个人建立一个网站要多少钱拓者设计吧室内设计官网登录
  • 如何提高网站的搜索排名备案查询网
  • 赣州市网站建设成都高新区规划国土建设局网站
  • 网站建设开票内容些什么东莞企业网站建设设计
  • 做携程怎样的网站织梦网站图标更换
  • 易展 网站建设iis7创建网站