设计基础决定上层建筑之go协程
作者:互联网
文章目录
强调,该文的整理内容图片全部来自幼麟实验室
内存管理模型
- 说协程,为啥先开始了内存呢?
不管是啥程,它的信息都要到内存,内存是怎么管理的直接影响上层建设啊,说的在理
- 内存隔离的必要性
又要从历史说起,刚开始 人们用内存的时候 很直接,操作系统用哪个,你用哪块,我用哪块 都知道,很容易打架
- 虚拟内存的出现,它是怎么设计的呢?
先说说历史原因,当时人们觉得4G好大啊,硬件水平也不支持,主流32位处理器
完美利用每一位
1、虚拟内存到物理内存是以页为单位映射的
2、页目录的设计也是以页为单位:一个地址32位=4字节,那么页目录只有1024个地址,一个页目录地址对应一个页表
3、页表的设计也是以页为单位:一个地址32位=4字节,那么每一个页表也是1024个地址
根据页表的一个地址寻址到物理内存页;每个页表中的地址代表一个物理内存页的起始地址,而且必须是4K的整数倍=低12位必须是0,因此,页表中的每一个地址都有12位的空闲空间可以使用,可以用来标识对应物理内存页是否可读、可写、可执行等信息
4、物理内存中每4KB作为一页
- OS是怎么管理虚拟内存的呢?
1、进程向OS
申请
内存时,通常不会一申请就立马分配,OS一般是先记个帐
,记录内存分配的链表就是在上面说到的页表地址
中进行标记,xxx地址被申请了,但是,真正的映射要到进程访问这段内存时才会进行,所以,进程的虚拟地址空间只是它可以申请使用的一个范围,只有真正映射到物理内存,才算是能够合法使用的虚拟内存2、CPU使用的也是
线性地址
,CPU中组件中有个MMU专门处理
虚拟地址到物理地址的转换专门的寄存器会存储页目录的物理地址,根据页目录到页表再到物理内存页,就可以正常寻址了。但是
,每次这么寻找一下会慢啊,好,那就缓存
一下 MMU独立一个TLB,用于存储该进程用到的物理内存地址,如果发生进程切换,TLB也会被保存和恢复,所以,进程切换代价高啊
3、所以,虚拟内存是先申请,运行时分配
,如如果发现未分配,就拐回去看看该进程是否申请了;如果申请了就帮忙映射,没申请就报异常。为什么这么设计呢?
首先,想想是人设计的,之前我就说过,人的设计无非是高效 节约 保障
官方回答:为了保障系统运行效率,因为内存映射比较耗时
进程 线程
- 进程是怎么管理虚拟内存的呢?
为什么虚拟地址空间要被划分为用户空间和内核空间呢?大牛为什么要这么做呢?
高效?节约?保障?
这次是为了进一步保障进程的运行安全
所有进程共享内核空间
-
进程调用OS的接口时,是怎么管理虚拟内存的呢?
-
线程在CPU上切换
为什么要切换?
1、由于时间片很短,所以用户感觉不到程序的切换过程
2、又因为CPU执行的很快,所以即使很短的时间片,也足够执行很多很多的指令
怎么切?
线程是进程中的一个执行体,拥有一个执行入口,以及从进程虚拟地址空间中分配的栈(包括用户栈和内核栈)
操作系统会
记录线程控制信息,栈基 栈指针 指令指针
协程
- 概念很重要,又一个吧决定权交给用户的例子
协程,
用户态的线程
既轻量又灵活的 由用户态进行调度的 多任务模型
1、创建时,都要指定执行入口,底层都会分配协程执行栈和控制信息,否则又该如何实现用户态调度;
2、让出执行权时,也都要保存执行现场,不然如何能够从中断处恢复执行;
3、协程的核心思想
在于控制流的主动让出
和恢复;
4、每个协程拥有自己的执行栈,可以保存自己的执行现场,所以,把权力交给用户,按需
创建协程;
- go的出现为什么强调协程?
1、因为高并发成为主流趋势,瞬间海量请求让多进程模型下,内存告急,内核态和用户态两头忙
2、表现在IO多路复用中
1、通过IO多路复用,线程再也不用为等待某个socket而阻塞或空耗CPU了,并发大大增加
2、epoll的实现方式是比较好的,但,它的问题是?一次没读完,需要保存现场,等待下次CPU调度
3、那么,epoll需要的正是协程自带的,不CP一下说不过去啊
注:
同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)
阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.
- 协程和多路复用CP的好处
1、保留IO多路复用的性能
2、解耦
业务逻辑和控制逻辑,把业务逻辑交给用户
3、read write connect 包装一下,实现IO事件注册和主动让出
标签:协程,进程,地址,内存,页表,go,虚拟内存,上层建筑 来源: https://blog.csdn.net/u013616005/article/details/114181796