文章目录
从下面的图片和代码当中可以看出子进程对全局变量进行修改,而父进程的值却没有变,这也就说明进程具有
独立性
,两个值互相并不影响是使用写实拷贝
的原因。
它们的值不行同,但地址确是相同的,如果这个地址是物理地址的话是不可能的,所以这里表面使用的是虚拟地址或线性地址。
1 #includestdio.h>
2 #includeunistd.h>
3 #includeassert.h>
4
5
6 int a=100;
7 int main()
8 {
9 pid_t pt=fork();
10 while(1)
11 {
12 assert(pt>=0);
13 if(pt==0)
14 {
15 printf("我是子进程,pid是%d,ppid是%d,全局变量的值是%d,地址是%pn",getpid(),getppid(),a,&a);
16 a++;
17 sleep(1);
18 }
19 if(pt>0)
20 {
21
22 printf("我是父进程,pid是%d,ppid是%d,全局变量的值是%d,地址是%pn",getpid(),getppid(),a,&a);
23 sleep(1);
24 }
25
26 }
27 }
==============================================================================
在进程地址空间的这个结构体中所限制的区域,就是虚拟地址或者线性地址
pcb和地址空间之间的交互是通过虚拟地址交互的,页表的作用就是将虚拟地址映射到物理地址上。
下面的图片也就证实了,为什么一个地址可以有两个值,通过这个也可以理解为什么创建子进程的时候会有两个pid,原因就是在函数返回前都已经执行完了,子进程也是创建好了,之后就是谁先返回,谁就让OS发生写实拷贝。
如果没有虚拟地址,计算机是如何工作的
这样会因为
野指针
问题和越界
问题导致计算机工作出错,而有了虚拟地址,多了个软件层,需要先进行页表映射,就会多了层保障,虽然用了虚拟地址,但是并不能保证就不会出错。但是已经变得安全多了。
I
在之前C语言当中,char* str=“hello”;是不可修改的,原因也就是在地址映射的时候权限是只读的。
mallco的本质
当OS申请内存时,是申请时就给开辟空间还是需要时在开辟空间?答案是在需要时在开辟空间。
OS是不允许任何一点浪费和不高效的。
当malloc开辟空间时,先将虚拟地址弄出来,物理地址并不开辟空间,这属于缺页中断
。当要用时在开辟空间,在这个空挡之间物理地址也是可以给别人开辟空间,这也就说明物理地址开辟空间并不遵循什么规矩。
将进程管理
和内存管理
进行解耦合
。
地址空间可以让进程以统一的视角看待代码和数据。
虚拟地址的策略不只会影响OS
(就是防止一些野指针和越界),它还会让编译器
遵守该规则,编译器当中使用的都是虚拟地址。
CPU读到的数据也是虚拟地址。
当程序还没有加载到内存当中他就有了地址(虚拟地址),后来加载到物理内存当中他就有了两套地址,
在加载到cpu当中,使用的地址是虚拟地址。
在最后可以了解一下ELF格式
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net