by shihang.mai
1. 操作系统的启动
os启动os负责管理硬件(kernel 内核)和进程
2. 用户态和内核态
cpu分不同的指令级别
- linux内核跑在ring 0级
- 用户程序跑在ring 3级
对于系统的关键访问,必须通过kernel。jvm运行在用户态。
2.1 进程 线程 纤程
进程和线程有什么区别?
- 进程是OS分配资源的基本单位,
- 线程是OS执行调度的基本单位。
- 分配资源最重要的是内存空间,线程共享进程的内存空间,没有自己独立的内存空间。
在linux中线程其实就一个普通进程,用了一个fork()函数,底层用的Clone(),copy一个新的进程出来,而启动线程用exec()
纤程
- jvm运行在用户态,OS运行在内核态,而在jvm new thread(),对应在OS创建一个线程(lwp ligth weight process),所以是一个重量级线程。
- Fiber 是线程里的线程,运行在用户态,在jvm启动一个线程,而多个Fiber创建在这个线程上,这样做,Fiber不需要与OS交互,速度快。
linux中维护一个进程用的是一个进程描述符PCB(process control block)
僵尸进程
父进程,fork()出子进程,而父进程维护子进程的pcb,子进程退出,由父线程释放。如果父进程没释放,子进程成为了一个僵尸进程。可以用操作系统中的wait()方法手动释放。
孤儿进程
子进程结束之前,父进程已退出。linux一般会把这些个子进程,全部归为一个父进程(init进程)
3. 进程调度
每个进程均有自己的一个调度策略,并且可以自定义的,一般linux都有自己内置的调度。
多任务调度:非抢占式 、抢占式
Linux2.5采用经典Unix O(1)调度策略.用的是时间片调度。每个进程固定使用时间片,这个策略偏向服务器,对交互不友好。
Linux2.6.23后,采用CFS complete fair scheduler 完全公平调度算法.按优先级分配时间片比例,记录每个进程的执行时间,如果有一个进程执行时间不到它应该分配的比例,优先执行。
3.1 进程调度基本概念
进程类型:IO密集型 CPU密集型
进程优先级:实时进程>普通进程
3.2 LINUX默认的调度策略
对于实时进程:sched_fifo(优先级高的先执行)和sched_rr(轮询)
对于普通进程:CFS,按优先级调度
4. 中断
硬中断:键盘,打印机等。
软中断(system call系统调用):软件发出的中断,即通俗的80中断。
- 系统调用int 0x80(16进制是0x80 10进制是128 2进制是1000 0000)或者sysenter原语(新的CPU支持),放入128到ax寄存器,
- 内存中固定位置有一个中断描述符表(key 0 1 2 128--255 value callback),调用128对应的callback函数(内核callback函数的位置)
- 在调用callback前,保护现场,即将当前进程状态保持(将原来寄存器的东西放回当前进程)
- 切换用户态到内核态。再内存中读取参数传入bx cx dx si di寄存器,运算后,返回值放入ax返回
5. 内存管理
多进程放入内存,要解决2个问题
- 内存撑爆-分页装入
- 进程间互相打扰-虚拟内存
解决这两个问题,诞生了现在的内存管理系统:虚拟地址 分页装入 软硬件结合寻址
分页装入:程序分为一块一块的,内存中也分为一块一块的(page frame),4k。用到程序的那一块就装入那一块到内存。当内存满了,回采用LRU算法,将最不常用的放到swap分区。
虚拟内存:让程序工作在虚拟空间,程序用到的空间地址不再是物理地址,而是虚拟地址,这样A进程永远不可能访问B进程的空间,虚拟空间的大小=寻址空间(64位系统 2^64 byte 32位系统2^32 byte),比物理空间大很多。站在虚拟的角度,每个进程独享整个系统+CPU
软硬件结合寻址:段的基地址+逻辑地址(偏移量)=线性地址,而线性地址映射到物理地址,用了OS+一个硬件MMU完成的
6. 内核同步方法
以下几个类型,保证一个或多个 原子性 有序性 可见性
- 原子操作-内核中类似于AtomicXXX,compare and exchange
- 自旋锁-内核中通过汇编支持的cas
- 读写自旋-类似ReadWriteLock,可同时读,只能一个写.读的时候是共享锁,写的时候是排他锁
- 信号量-类似于Semaphore,重量级锁,线程会进入wait
- 互斥体-特殊的信号量,平时说的锁大多说这个
- 顺序锁-序列计数器,从0开始,读的时候不改变,当写的时候+1,写完再+1,如果是偶数直接读,不是偶数证明有在写。
网友评论