操作系统
- 内存管理
- 驱动管理
- 进程、线程、协程
- 文件系统
内存
- 32位 2**32 == 4G
- DOS时代,内存是程序自己控制,不相互隔离(淘汰)
- Windows,统一的内存空间,(每个程序看到的内存地址都是相同)
- 存储器山 cache miss
- CPU n核心 ALU cpu寄存器(速度最快)
- 每个核心有L1,L2
- 对整个 CPU 而言的L3缓存,3M
- 内存,可以很大 8G
- 硬盘
- 网络传输
- 虚拟存储器 统一的内存模型
- 一个程序4G, 内存+硬盘
- eg:电脑4G,a程序1G数据->内存,页表, b程序1G数据->内存,页表(把4G映射)
此时有一个c程序3G, 要使用,此时把a存储,把 c 程序 load 进来(换)换入换出 - a ->查页 page fault => page load => 正常运行
- 也有不经过CPU的,DMA
驱动
- 驱动是对硬件层的抽象
- 键盘:ps/2, usb, bluetooth
- linux:统一成文件 接口 read write seek
文件系统
- original数组,在数组开始存储:[meta元信息 对应的文件位置(偏移量) 对应的文件大小]
- 格式化: 会把所有信息抹掉,浪费时间
- 快速格式化: meta清空,剩下的只是一堆无解的二进制
- 抽象加密:所有的文件,都在一个file里
- /main/main.py -> file load -> execute
进程、线程、协程
- DOS时代,没有Process概念
- 进程(操作系统,调度资源的最小单位)有pid:ps aux
- 实现原理:时间片;进程通信:pipe, file, socket
- 多线程 multithreading,thread 或者 lightweight process,线程是进程中的一个实体
- 多个线程共享一个进程资源的全局数据
- 对于一个进程来说,你持有一个页表
- 对于同一个进程内的线程,你将共享同一张页表
- 多线程同步问题
数组 支持add
把数组size + 1
把add的这个数字放在 data[size]
有2个线程,同时去add
A线程 走了1
B线程 走了1
A 存了数据 data[size] = xxx
A 存了数据 data[size] = xxx
核心在于,操作被拆分了
解决:
atomic swap_and_cmp
加锁,mutex 互斥锁, 信号量, 读写锁, 自选锁。
同步:
加锁后,我对这个资源有所有权
在我的所有操作没有结束前,其它线程要等
问题: 同步后,可能死锁(哲学家进餐)- 为什么死锁?获取资源的顺序不一样
对于底下哲学家 先1后2
对于上面哲学家 先2后1
所有的哲学家都是先1后2
- 调整最后一个人的顺序
- 如果我那不到右手,那我左手的也不要
- 为什么死锁?获取资源的顺序不一样
线程安全的交换数据的函数
获取资源顺序一致,先lock内存大的
swap(a,b)a.lock()
b.lock()
exchange(a.data, b.data)
a.unlock()
b.unlock()swap(a,b) —— swap(b,a) 死锁
- 超线程,一个CPU内核跑两个线程,inter技术
协程: 由程序自身控制,一个线程执行。一个线程里面I/O操作特别多,就用协程。
协程就是你可以暂停执行的函数,
Python not use multithread? GIL global interpreter lock - 并发(Concurrency)和并行(Parallelism)
- 并发,不管多少线程,只有系统能同时处理多个事情,就是并发(时间片内)
- 并行和多线程,多进程有关系,(精确的同时)
- 同步异步(信号触发)
- 事件发生不发生,是通过自己去检查得到的。
- 事情的发生,别人通知给你的。
- 阻塞与非阻塞
- 阻塞, 等下去
- 非阻塞, 不等
- 编译和解释
编译 -> 代码 -> 另一种代码 -> 编译到机器码 , 目标代码就是 机器码
解释 : c 语言是统一的,用c写了一个虚拟机, 这个虚拟机是可以部署到任何机器的
Python就是逐步转换成虚拟机指令
JIT: just in time complier, hybrid混合方案,把最热的代码编译到机器码 - 动态静态语言
- 动态静态: 赋值决定
- 强类型弱类型: 1 + ‘1’ JS弱;1 + 1 Python强类型
- 有 GC 无 GC: garbage collection 垃圾回收
new 和 delete, // malloc free c, c++
有GC的语言:java golang python ruby scala js
GC实现
- mark & sweep concurrent
- ref counting
Python 主要用ref counting, 解决不了用特殊的mark sweep