【Linux】进程控制(一)进程创建(原理+接口调用)及虚拟地址空间

虚拟地址空间

为什么要有虚拟内存?

认知这张图吗?之前说这是计算机物理内存的数据分布图
在这里插入图片描述
一个进程运行时需要将数据保存到内存中,如果每个进程运行时都直接控制物理内存地址,那就会造成:

  1. 不同进程访问同一块物理空间,数据安全不可控;
  2. 对于有限的物理内存,同时有大量进程时每个进程只能占用一小部分空间;
  3. 进程无法直接自己分配空间,因为并不能确定某一块空间其他进程是否正在使用;
  4. OS也无法直接为每个进程分配空间,因为进程开始前OS也不确定其具体需要多少空间;

因此OS为了更方便、更安全的为进程分配物流内存,就有了虚拟内存机制


什么是虚拟内存

虚拟内存就是一种OS内存管理的概念,可以说上面的内存分布图其实是虚拟内存的分布,而显示物理内存的分布更为复杂。
在这里插入图片描述

对于每个进程来说:

  • OS为每一个进程都虚拟出一个4G的虚拟内存地址空间(32位);
  • 进程的数据还是存放在真实的物理内存中,且真实物理内存是有限的(至少4G 32位)
  • 物理地址的数据存放并不是连续的,且虚拟地址与物理地址并不是一一对应,一般一个进程开辟的虚拟内存实际使用大小远小于真实大小
  • 程序不能直接访问真实的物理内存地址空间,都是通过虚拟地址与物理地址的转换(OS转换)
    在这里插入图片描述

子进程创建 && 写时拷贝原理

fork()函数与父子进程的概念息息相关,如果不了解父子进程,可以看看这个:进程概念——父子进程、僵尸进程和孤儿进程

进程创建接口函数fork()

在这里插入图片描述


fork()函数是系统调用函数

在这里插入图片描述


fork()函数调用的内部情况

1. 通过fork()函数观察虚拟内存机制

从之前 父子进程 的例子中就看到,即使父进程拷贝出的子进程中两者变量地址相同,但两进程互相并不干扰
在这里插入图片描述
原因就是进程对数据的操作是发生在虚拟内存上的,不同进程有不同的虚拟空间映射表

2. fork()函数采用写时拷贝

什么是写时拷贝

  • 一个进程除了自己的PCB进程信息,还有运行时的内存数据信息
  • 子进程是在父进程运行过程中完全拷贝了父进程的PCB信息;
  • 对于内存数据,当子进程不修改内存数据时,父子进程完全共享同一块物理内存数据;一但父子进程某一方修改了内存数据,为了父子进程独立性,OS会为修改数据的进程新开辟一块内存并拷贝存放这个要修改的数据,这就是写时拷贝

    字面理解:父子进程只有“写数据”时现实物理空间会发生拷贝,否则公用。

  • 写时拷贝时OS为节省内存空间而实现的管理内存机制。

3. fork()函数的具体流程:

  1. 给子进程分配新的内核数据结构(PCB存放在内存的内核区),并拷贝父进程PCB信息;

  2. 子进程拷贝父进程页表,实现内存共享

    刚创建后,OS并没有为子进程开辟新的空间存放父进程的内存数据,父子进程共享物理内存数据;

    如果不改变变量值,父子进程会一直共享一块数据

    一旦改变变量值,才以写时拷贝的方式拷贝一份(并更新页表)。此时父子进程通过各自的页表,指向不同的物理地址(只读部分仍在物理内存上公用

  3. 将子进程添加到系统进程追中(添加到双向链表中);

  4. fork返回后,开始调度器(OS进行)调度;

  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值