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

柳州建站电商网站开发过程是什么

柳州建站,电商网站开发过程是什么,文字游戏做的最好的网站,优秀网站设计欣赏案例文章目录 引言📘正文📖问题引入📖虚拟空间划分📖真实空间分布🖋️代码实现🖋️问题反思 📖进程地址空间🖋️虚拟地址🖋️页表MMU🖋️写时拷贝 📕各…

文章目录

  • 引言
  • 📘正文
    • 📖问题引入
    • 📖虚拟空间划分
    • 📖真实空间分布
    • 🖋️代码实现
    • 🖋️问题反思
  • 📖进程地址空间
    • 🖋️虚拟地址
    • 🖋️页表+MMU
    • 🖋️写时拷贝
  • 📕各部分结构的详细说明
    • 🖊地址空间布局图
    • 🖊代码段
    • 🖊数据段
    • 🖊 BSS段
    • 🖊堆(Heap)
    • 🖊 栈(Stack)
    • 🖊C代码示例:进程地址空间
  • 结语:进程地址空间的哲学意义

在这里插入图片描述

引言

在操作系统的浩瀚宇宙中,进程地址空间犹如一片神秘的荒原,深藏着无数的秘密与可能性。它是每一个程序运行的根基,是虚拟与现实交汇的地方,是计算机内存的魔法世界。它存在于操作系统的心脏之中,伴随着进程的诞生与死灭,演绎着一场关于资源管理与控制的永恒故事。

今天,我们将一起穿越这片无形的疆域,去探讨进程地址空间的奥秘,去感受它在操作系统中的重要地位与深刻影响。

对于 C/C++ 来说,程序中的内存包括这几部分:栈区堆区静态区 等,其中各个部分功能都不相同,比如函数的栈帧位于 栈区,动态申请的空间位于 堆区,全局变量和常量位于 静态区区域划分的意义是为了更好的使用和管理空间
他们的结构排布如图所示。那么真实物理空间也是如此划分吗?多进程运行 时,又是如何区分空间的呢?写时拷贝 机制原理是什么?本文将对这些问题进行解答.

内存条:真实的物理空间,用来存储各种数据

在这里插入图片描述

📘正文

📖问题引入

地址是唯一的,对地址进程编号的目的是为了不冲突

这是个耳熟能详的概念,在 C语言 学习阶段,我们可以通过对变量 & 取地址的方式,查看当前变量存储空间的首地址信息

#include <stdio.h>int main()
{const char* ps = "这是一个常量字符串";printf("字符串地址:%p\n", ps);  //%p 专门用来打印地址信息return 0;
}

linux下的执行结果
在这里插入图片描述
利用前面学习的 fork 函数创建子进程,使得子进程和父进程共同使用一个变量
代码示例如下:

  1#include<stdio.h>2 #include<unistd.h>3 #include<sys/types.h>4 #include<sys/wait.h>                                                                                                                                                                                          5 #include<stdlib.h>6 int main()7 {8     int val=10;9     pid_t id=fork();10     if(id==0)//子进程11     {12         val*=2;13         printf("我是一个子进程,pid: %d ppid : %d 共享值: %d 共享值地址: %p\n",getpid(),getppid(),val,&val);14         exit(0);15     }16     waitpid(id,0,0);17     printf("我是父进程,pid: %d ppid: %d 共享值: %d 共享值地址: %p\n",getpid(),getppid(),val,&val);18     return 0;19 }

在这里插入图片描述

可以看到,针对同一个地址相同的值val,二者打印出来的共享值却不同,难度一个数可以同时拥有两个不同的值吗,这显然是不可能的。

这与之前提到的fork有两个返回值原理类型,都利用了写时拷贝

因为真实地址都是 唯一 的,分析:

  • 不同的空间出现同名的情况
  • 父子进程使用的真实物理空间并非同一块空间!

原因

  • 当子进程尝试修改共享值时,发生 写时拷贝 机制
  • 语言层面的程序空间地址不是真实物理地址
  • 一般将此地址称为虚拟地址线性地址

结论: 语言层面的地址都是虚拟地址,用户无法看到真实的物理地址,由 OS 统一管理

📖虚拟空间划分

一般用户的认知中,C/C++ 程序内存分布如下图所示,直接表示内存中的各个部分

在这里插入图片描述

📖真实空间分布

但实际上的空间分布是这样的:
在这里插入图片描述
如果有多个进程(真实地址空间只有一份),此时情况是这样的:
在这里插入图片描述

🖋️代码实现

在实现虚拟地址空间时,是用结构体mm_struct实现的

task_struct一样,mm_struct 中也包含了很多成员,比如不同区域的边界值

//简单展示其中的成员信息
mm_struct
{//代码区域划分unsigned long code_start;unsigned long code_end;//堆区域划分unsigned long heap_start;unsigned long heap_end;//栈区域划分unsigned long stack_start;unsigned long stack_end;//还有很多其他信息……
}

因此其程序地址空间的管理,也就是区域划分,只需要修改不同区域的startend即可.

每个进程都会有这样一个 mm_struct,其中的区域划分就是虚拟地址空间

  • 通过对边界值的调整,可以做到不同区域的增长,如堆区、栈区扩大

  • mm_struct 中的信息配合 页表+MMU 在对应的真实空间中使内存(程序寻址)

🖋️问题反思

此时可以理解为什么会发生同一块空间能读取到不同值的现象了

父子进程有着各自的 mm_struct,其成员起始值一致

  • 对于同一个变量,如果未改写,则两者的虚拟地址通过 页表 + MMU 转换后指向同一块空间
  • 发生改写行为,此时会在真实空间中再开辟一块空间,拷贝变量值,让其中一个进程的虚拟地址空间映射改变,这种行为称为 写时拷贝

刚开始,父子进程共同使用同一块空间
在这里插入图片描述

在发生改写行为后,子进程在真实空间内重新开辟一块空间,拷贝变量值改下,虽然此时的虚拟地址仍为初始值,蛋映射关系已经发生变化。
在这里插入图片描述

📖进程地址空间

下面来好好谈谈 进程地址空间 (虚拟地址)

🖋️虚拟地址

在早期程序中,是没有虚拟地址空间的,对于数据的写入和读取,是直接在物理地址上进行的,程序与物理空间直接打交道,存在以下问题:

  • 假设存在野指针问题,此时可能直接对物理内存造成越界读写
  • 程序运行时,每次都需要大小为 4GB 的内存使用,当进程过多时,资源分配就会很紧张,引起进程阻塞,导致执行效率下降
  • 动态申请内存后,需要依次释放,影响整体效率

在这里插入图片描述
为了解决各种问题,大佬们提出了 虚拟地址空间 这个概念,有了 虚拟空间 后,当进程创建时,系统会为其分配属于自己的 虚拟空间,需要使用内存时,通过 寻址 的方式,使用物理地址上的空间即可

  • 多个进程互不影响,动态使用,做到 效率、资源 双赢
  • 发生越界行为时,寻址 机制会检测出是否发生越界行为,如果发生了,能在其对物理地址造成影响前进行拦截
  • 因为每个进程都有属于自己的空间,OS 在管理进程时,能够以统一的视角进行管理,效率很高

光有 虚拟地址空间 是不够的,还需要一套完整的 ‘‘翻译’’ 机制进行程序寻址,如 Linux 中的 页表 + MMU

🖋️页表+MMU

页表本质上是一张表,一侧存储虚拟地址,另一侧存储所映射的真实物理地址。

操作系统 会为每个 进程 分配一个 页表,该 页表 使用 物理地址 存储。当 进程 使用类似 malloc 等需要 映射代码或数据 的操作时,操作系统 会在随后马上 修改页表 以加入新的 物理内存。当 进程 完成退出时,内核会将相关的页表项删除掉,以便分配给新的 进程

系统底层机制的研究是非常生涩的,这里简言之就是 页表 记录信息,通过 MMU 机制进行寻址使用内存.

假设目标空间为只读区域(比如数据段、代码段),在进行空间开辟时,会打上只读权限标签。后续对这块进行写入操作时,会直接拒绝

🖋️写时拷贝

思考:为什么要采取写时拷贝映射开辟的方式进行存储呢?每一个数据直接存储不可行吗?

写时拷贝是一种为了优化空间和时间应运而生的操作,带有一定赌博成分。

  • 操作系统认为你对于数据的修改与存储操作相比,是较为低频的,因此采取偷懒的方式进行映射存储,多个进程中的共享数据均指向同一块存储空间,用来优化存储冗余多次构造的情况
  • 这一点在自定义类型时较为明显,内置类型的优化效率并不算高。

可以通过一个简单的例子来证明此现象

//计算 string 类的大小
#include <iostream>
#include <string>
using namespace std;int main()
{string s;cout << sizeof(s) << endl;return 0;
}

VS2022中
在这里插入图片描述
linux环境中
在这里插入图片描述
分析:

在代码中,string
s;定义了一个C++的字符串对象。虽然你没有给字符串分配任何内容,但是字节大小却不为0。这是因为不同的编译器和标准库实现可能会有不同的内存布局,通常会包括指向动态内存的指针、当前大小、容量和一些额外的管理信息。

📕各部分结构的详细说明

操作系统将进程地址空间划分为多个区域,每个区域用于存储特定类型的数据。以下是典型的地址空间布局:

在这里插入图片描述
在这里插入图片描述

🖊地址空间布局图

以32位操作系统为例,地址空间布局如下:

+---------------------------+  0xFFFFFFFF
| 内核空间                  |  
+---------------------------+  0xC0000000
| 用户栈                    |
+---------------------------+
| 动态分配的堆(Heap)      |
+---------------------------+
| BSS段                    |
+---------------------------+
| 数据段                    |
+---------------------------+
| 代码段                    |
+---------------------------+  0x00000000

🖊代码段

  • 存储内容:存放程序的可执行代码。
  • 访问权限:只读,防止程序意外修改指令。
  • 特点:多个进程可以共享同一段代码段(如共享库)

🖊数据段

  • 存储内容:存储已初始化全局变量静态变量
  • 访问权限:读写权限。
  • 特点:程序运行时大小固定。

🖊 BSS段

  • 存储内容:存储未初始化全局变量静态变量
  • 特点:初始值默认为0,占用物理内存时才分配。

🖊堆(Heap)

  • 存储内容:动态分配的内存(如malloc、new分配的内存)。
  • 特点:向高地址增长;由程序员手动分配和释放。

🖊 栈(Stack)

  • 存储内容:局部变量函数调用参数返回地址等。
  • 特点:向低地址增长;由操作系统自动管理,超出范围会触发栈溢出。

上面的几种是主要的几种,还有几个小的内存区,比如字符段常量区字符常量区的内容不能修改,只有读权限

🖊C代码示例:进程地址空间

以下代码展示了不同段的地址空间位置。

#include <stdio.h>
#include <stdlib.h>int global_var = 10;  // 全局变量(数据段)
int uninit_var;       // 未初始化变量(BSS段)void print_addresses() {int local_var = 20;  // 局部变量(栈)void *heap_var = malloc(10);  // 动态内存(堆)printf("代码段地址: %p\n", (void*)print_addresses);printf("全局变量地址: %p\n", (void*)&global_var);printf("未初始化全局变量地址: %p\n", (void*)&uninit_var);printf("局部变量地址: %p\n", (void*)&local_var);printf("堆变量地址: %p\n", heap_var);free(heap_var);
}int main() {print_addresses();return 0;
}

输出示例:

代码段地址: 0x401000
全局变量地址: 0x601020
未初始化全局变量地址: 0x601030
局部变量地址: 0x7ffd25d3f8bc
堆变量地址: 0x55d3ecf1b260

在这里插入图片描述

结语:进程地址空间的哲学意义

进程地址空间的概念,超越了技术的范畴,它涉及到操作系统如何管理和控制内存,如何为每个进程提供一个独立而安全的运行环境。在这个过程中,虚拟内存技术则如同魔法师一样,巧妙地将虚拟世界与现实世界结合在一起,为开发者创造出一个更加自由和高效的编程环境。

在这个隐形的、却至关重要的空间中,进程的每一次启动、每一次执行、每一次销毁,都在演绎着一场关于资源管理、内存控制与程序执行的深刻哲学思考。正如人生的每一个阶段,进程地址空间也在默默地展示着操作系统的智慧与魅力,成为计算机科学中不可或缺的一部分。

本篇关于进程地址空间的介绍就暂告段落啦,希望能对大家的学习产生帮助,欢迎各位佬前来支持斧正!!!

在这里插入图片描述

http://www.dtcms.com/wzjs/788731.html

相关文章:

  • 网站建设及政务工作自查爱客wordpress源码
  • wordpress图片命名搜索引擎优化的要点
  • 怎样建设网站网站管理手册
  • 食品 药品 监督 网站 源码 php高端定制开发网站
  • 自己做的网站二维码怎么做的代理商入口
  • 科技网站的一些案例展示制作网页时不能使用图案作为网页背景
  • 网站排名费用开网站建设公司挣钱吗
  • 免费移动网站模板大兴网站建设报价
  • 自己开公司小红书关键词排名优化
  • 企业网站优化服务主要围绕哪些要素泉州关键词排名工具
  • 网站竞争对手如何做调研wordpress手机站和pc如何切换的
  • 国外做兼职网站设计网站建设投标书免费
  • 苏州诗华洛网站建设网站 微信认证
  • 重庆营销网站建设公司开原铁岭网站建设
  • php个人网站模板下载万户网络学校网站建设
  • 西安网站优化wordpress 头条插件
  • 烟台网站建设工资有wordpress
  • 大学网站建设情况汇报怎样建网站得花多少钱
  • 深圳龙岗区住房和建设局网站企业注册很多网站的好处
  • 建阳网站建设wzjseo南阳网站运营
  • 如何制作社交网站无锡做网站优化哪家好
  • phpcms 网站模板网站制作服务
  • 网站开发考核怎么查百度搜索排名
  • 网站哪里有小工程施工合同协议书
  • 男女做羞羞羞的网站教育投资网站建设方案
  • 泰州网站制作工具网站不支持php
  • 创建网站的工具如何创建自己的网址链接?
  • 如何增加网站的流量大连企业网站
  • 带注册的网站需要多大空间网站建设宀金手指花总十四
  • 电子商务网站建设主题安卓app快速开发