【Linux学习笔记】进程概念(下)

  • 进程地址空间
    • 1. 虚拟地址
    • 2. 什么是进程地址空间
    • 3. 进程地址空间的映射。
    • 4. 地址空间存在的意义
    • 5. 写时拷贝

进程地址空间

1. 虚拟地址

来看这样一段代码。

#include <stdio.h>
#include <unistd.h>int global_value = 100;int main()
{pid_t id = fork();if(id < 0){printf("fork error\n");return 1;}else if(id == 0){int cnt = 0;while(1){printf("我是子进程, pid: %d, ppid: %d | global_value: %d, &global_value: %p\n", getpid(), getppid(), global_value, &global_value);sleep(1);cnt++;if(cnt == 10){global_value = 300;printf("子进程已经更改了全局的变量啦..........\n");}}}else{while(1){printf("我是父进程, pid: %d, ppid: %d | global_value: %d, &global_value: %p\n", getpid(), getppid(), global_value, &global_value);sleep(2);}}sleep(1);
}

运行结果:

img

上面的这种现象,是因为这里所打印出来的地址并非物理地址,而是虚拟地址。所以这里就引出了进程地址空间。下面用个例子来描述进程地址空间。

img

img

其中所画的大饼是需要管理起来的,好比老板昨天让员工好好干,一个月后升经理。但是今天老板见员工,却说一个月升总监。大饼画的多了,自然就需要管理起来,否则容易混乱。对于软件来说,管理的本质就是先描述,再组织。所以这里的一个个大饼,其实可以理解为是一个个的结构体。img

2. 什么是进程地址空间

  1. 进程地址空间的概念

上面讲过操作系统给进程画的大饼可以认为是进程地址空间,具体来说就是一个结构体。那结构体里面有什么呢?

首先,先做好规定,这里的背景是32位机器背景。

  1. 32位机器的数据可以有2^32个,约42亿,以字节为单位。
  2. 所以表示的空间大小约为4GB的空间范围。
  3. 地址确保唯一性,所以有2^32个地址。

所以,进程地址空间整体上应该是这样的,如下图:

img

对于上面的这个图,你可以想象成一把尺子。尺子是有刻度,所以就可以用刻度来划分区域。可以用一个结构体描述出上面的进程地址空间。如下结构体:

struct mm_struct
{unit_32t code_start;unit_32t code_end;unit_32t data_start;unit_32t data_end;unit_32t heap_start;unit_32t heap_end;//......
}

所以可以认为有这么一个进程地址空间对应着这么一个结构体,其中结构体的变量就是地址,这些地址就如同尺子上的刻度,划分好了区域。

img

其中堆栈空间是动态开辟的,所以当你写代码定义变量或者new变量的时候,其实就是在更改对应区域的start or end。

3. 进程地址空间的映射。

程序当加载到内存的时候,确实是加载到了物理内存里面,但是操作系统并不允许进程直接访问物理内存,而是在进程PCB里面存放一个进程地址空间,让进程地址空间通过页表和物理地址进行映射,从而让进程可以访问到物理内存。如图所示:img

所以进程是无法直接访问到物理地址的,是操作系统在管理进程的时候,同时给进程画了个大饼,让进程可以通过进程地址空间,再通过页表的映射,从而访问到物理地址。

4. 地址空间存在的意义

  1. 为了保护物理地址

设想一下,如果一个进程可以随意访问物理地址,然后这个进程将数据恶意写入到物理地址,将会破坏物理地址。操作系统为了保证物理地址的安全,就有了地址空间。通过地址空间的虚拟地址,再通过页表映射访问到物理地址,保证了物理地址的安全。

用压岁钱的例子来解释上述内容。你的压岁钱实际就是物理地址,但是中间有父母(页表)的存在,所以你确实是知道有那么多钱,但是当你用的时候,要通过父母的同意,如果父母觉得你的要求合理,那么就通过你的要求,让你拿到钱去买东西。如果要求不合理,那么父母将会拒绝你的要求,拒绝给你拿钱。

img

  1. 为了保证进程间的独立性

具体可看下面写时拷贝的内容。

5. 写时拷贝

回到我们的第一个代码打印结果的问题,可以看到两个值的地址明明一样,但是值却不一样。这是为什么呢?

是由于进程具有独立性,虽然两个进程共享数据,但是每个进程都是有独立的进程地址空间和独立的页表。

img

因为进程有独立性,所以先有一个进程改变了global_value的值,也不会影响另一个进程的值。这是因为在有一个进程改变值的时候,OS会先进行数据拷贝,在物理地址上开辟空间,拷贝进去,然后更改另一个进程页表的映射。

img

所以这也就是打印结果的时候,为什么地址明明一样,但是两个进程的数值却不相同,是因为操作系统帮进程做了写时拷贝的操作,写时拷贝对虚拟地址无影响。所以这也证明了,打印出来的并非物理地址,而是虚拟地址。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

非关系型数据库Redis的安装【Linux】及常用命令

前言 Redis&#xff08;Remote Dictionary Server&#xff09;是一种开源的内存数据库管理系统&#xff0c;它以键值存储方式来存储数据&#xff0c;并且支持多种数据结构&#xff0c;如字符串、哈希、列表、集合、有序集合等。Redis最初由Salvatore Sanfilippo开发&#xff0c…

苹果cms论坛多播放源自动采集在线影视网站

苹果 cms 论坛一个基于 vue 和 gin 实现的在线观影网站 项目采用 vite vue 作为前端技术栈, 使用 ElementPlus 作为 UI 框架进行开发 后端程序使用 Gin gorm go-redis 等相关框架提供接口服务, 使用 gocolly 和 robfig/cron 进行公共影视资源采集和定时更新功能 目前用户…

vscode debug skills

1) VSCode 调试 C/C 代码时&#xff0c;如何显示动态分配的指针数组。 创建一个动态分配的一维数组: int n 10; int *array (int *)malloc(n*sizeof(int)); memset(array, 1, n*sizeof(int)); 如果直接 Debug 时查看 array 指针&#xff0c;并不能看到数组所有的值。 查看…

行业揭秘:腾讯共享wifi码推广零加盟费是真的吗?

近年来&#xff0c;“共享经济”概念在商业领域取得了巨大成功。共享WiFi贴码成为共享经济的一种典型案例&#xff0c;被越来越多的人看作是一种低风险、高回报的投资方式。而在这个市场中&#xff0c;腾讯WiFi码推广以“零加盟费”而备受关注。本文将探讨腾讯WiFi码推广零加盟…

uniapp 使用 UDP

一、搭建UDP服务端&#xff0c;nodejs const dgram require("dgram");const message Buffer.from("你好&#xff0c;这是一个UDP广播消息"); const port 3000; // 用你想要的端口替换这里// 创建一个UDP套接字 const socket dgram.createSocket("…

pytorch笔记 GRUCELL

1 介绍 GRU的一个单元 2 基本使用方法 torch.nn.GRUCell(input_size, hidden_size, biasTrue, deviceNone, dtypeNone) 输入&#xff1a;&#xff08;batch&#xff0c;input_size&#xff09; 输出和隐藏层&#xff1a;&#xff08;batch&#xff0c;hidden_size&#xf…

服务器遭受攻击如何处理(记录排查)

本文的重点是介绍如何鉴别安全事件以及保护现场的方法&#xff0c;以确保服务器负责人能够在第一时间对安全攻击做出反应&#xff0c;并在最短时间内抵御攻击或减少攻击所带来的影响。 在服务器遭遇疑似安全事件时&#xff0c;通常可以从账号、进程、网络和日志四个主要方面进…

ssh登录界面变成vim提示,进不去系统

是ubuntu系统 使用远程连接root&#xff0c;进去后发现界面变成vim编辑器的介绍界面了 使用普通用户登录 查询用户的登录shell是不是有问题 sudo vim /etc/passwd 发现用户shell变成了vim编辑器 修改为/bin/bash就可以正常登录了 重新登录测试就正常了

华为云服务器,在线安装MySQL

需求 在华为云服务器上&#xff0c;部署MySQL数据库&#xff0c;通过 公网IP 访问数据库。 通过 yum &#xff0c;在线安装MySQL&#xff1b;配置远程连接&#xff0c;开放3306端口&#xff0c;能够通过公网访问。 云服务器配置说明 本文所使用的 华为云服务器 配置如下。 …

YOLOv5 - yolov5s.yaml 文件

基于深度学习的目标检测模型的结构:输入->主干->脖子->头->输出。主干网络提取特征&#xff0c;脖子提取一些更复杂的特征&#xff0c;然后头部计算预测输出。 YOLOv5网络结构主要由以下几部分组成: 骨干网络(Backbone) &#xff1a;Backbone:骨干网络&#xff0c…

【k8s】pod进阶

一、资源限制 1、资源限制的概念 当定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是 CPU 和内存大小&#xff0c;以及其他类型的资源。 当为 Pod 中的容器指定了 request 资源时&#xff0c;调度器就使用该信息来决定将 Pod 调度到哪个节点上…

如何本地部署Jellyfin影音服务器并实现在公网访问

文章目录 1. 前言2. Jellyfin服务网站搭建2.1. Jellyfin下载和安装2.2. Jellyfin网页测试 3.本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5. 结语 1. 前言 随着移动智能设备的普及&#xff0c;各种各样的使用需求也被开发出来&…