其他分享
首页 > 其他分享> > 设计基础决定上层建筑之go协程

设计基础决定上层建筑之go协程

作者:互联网

文章目录


强调,该文的整理内容图片全部来自幼麟实验室

内存管理模型

不管是啥程,它的信息都要到内存,内存是怎么管理的直接影响上层建设啊,说的在理

又要从历史说起,刚开始 人们用内存的时候 很直接,操作系统用哪个,你用哪块,我用哪块 都知道,很容易打架

在这里插入图片描述

先说说历史原因,当时人们觉得4G好大啊,硬件水平也不支持,主流32位处理器
完美利用每一
1、虚拟内存到物理内存是以页为单位映射的
2、页目录的设计也是以页为单位:一个地址32位=4字节,那么页目录只有1024个地址,一个页目录地址对应一个页表
3、页表的设计也是以页为单位:一个地址32位=4字节,那么每一个页表也是1024个地址
根据页表的一个地址寻址到物理内存页;每个页表中的地址代表一个物理内存页的起始地址,而且必须是4K的整数倍=低12位必须是0,因此,页表中的每一个地址都有12位的空闲空间可以使用,可以用来标识对应物理内存页是否可读、可写、可执行等信息
4、物理内存中每4KB作为一页

在这里插入图片描述

1、进程向OS申请内存时,通常不会一申请就立马分配,OS一般是先记个帐,记录内存分配的链表就是在上面说到的页表地址中进行标记,xxx地址被申请了,但是,真正的映射要到进程访问这段内存时才会进行,所以,进程的虚拟地址空间只是它可以申请使用的一个范围,只有真正映射到物理内存,才算是能够合法使用的虚拟内存

2、CPU使用的也是线性地址,CPU中组件中有个MMU专门处理虚拟地址到物理地址的转换专门的寄存器会存储页目录的物理地址,根据页目录到页表再到物理内存页,就可以正常寻址了。但是,每次这么寻找一下会慢啊,好,那就缓存一下 MMU独立一个TLB,用于存储该进程用到的物理内存地址,如果发生进程切换,TLB也会被保存和恢复,所以,进程切换代价高啊
3、所以,虚拟内存是先申请,运行时分配,如如果发现未分配,就拐回去看看该进程是否申请了;如果申请了就帮忙映射,没申请就报异常。为什么这么设计呢?
首先,想想是人设计的,之前我就说过,人的设计无非是高效 节约 保障
官方回答:为了保障系统运行效率,因为内存映射比较耗时

在这里插入图片描述

进程 线程

为什么虚拟地址空间要被划分为用户空间和内核空间呢?大牛为什么要这么做呢?
高效?节约?保障?
这次是为了进一步保障进程的运行安全
所有进程共享内核空间

在这里插入图片描述

为什么要切换?
1、由于时间片很短,所以用户感觉不到程序的切换过程
2、又因为CPU执行的很快,所以即使很短的时间片,也足够执行很多很多的指令
怎么切?
线程是进程中的一个执行体,拥有一个执行入口,以及从进程虚拟地址空间中分配的栈(包括用户栈和内核栈)
操作系统会记录线程控制信息,栈基 栈指针 指令指针

在这里插入图片描述

协程

协程,用户态的线程 既轻量又灵活的 由用户态进行调度的 多任务模型
1、创建时,都要指定执行入口,底层都会分配协程执行栈和控制信息,否则又该如何实现用户态调度;
2、让出执行权时,也都要保存执行现场,不然如何能够从中断处恢复执行;
3、协程的核心思想在于控制流的主动让出和恢复;
4、每个协程拥有自己的执行栈,可以保存自己的执行现场,所以,把权力交给用户,按需创建协程;

在这里插入图片描述

1、因为高并发成为主流趋势,瞬间海量请求让多进程模型下,内存告急,内核态和用户态两头忙
2、表现在IO多路复用中

1、通过IO多路复用,线程再也不用为等待某个socket而阻塞或空耗CPU了,并发大大增加
2、epoll的实现方式是比较好的,但,它的问题是?一次没读完,需要保存现场,等待下次CPU调度
3、那么,epoll需要的正是协程自带的,不CP一下说不过去啊
注:
同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)
阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.

在这里插入图片描述

1、保留IO多路复用的性能
2、解耦业务逻辑和控制逻辑,把业务逻辑交给用户
3、read write connect 包装一下,实现IO事件注册和主动让出

在这里插入图片描述

标签:协程,进程,地址,内存,页表,go,虚拟内存,上层建筑
来源: https://blog.csdn.net/u013616005/article/details/114181796