4. 进程是怎样调度的
什么时候会产生调度
你自己走: 出现(磁盘/网络)IO, 或者抢锁没抢到, 进入内核态后调用schedule函数
我赶你走: 时间片到了(通常是10ms), 下次进入内核态的时候schedule
我们换个角度看, 也就是进程从当前的 [运行态 → 阻塞/就绪/终止态]. 再加一个新建态就构成了一个进程所有可能的五个状态了. 这里面无论是因为什么原因, 调度函数都是在内核态里被调用的.
调度这之间发生了什么: ContextSwitch + 挑选下一个进程
更新进程的状态, 丢到对应的队列里去, 保存当前函数的PCB寄存器
通过某种方式挑出下一个进程
更新进程状态为运行态, 加载下个进程的虚拟内存表/PCB/寄存器(搞一次Context Switch)
如何挑选下一个进程: 调度算法负责挑选出下一个进程, 每一种调度算法都有自己的特点, 在你的场景下, 根据以下几个原则评估出适合你的调度算法:
CPU出于忙时的比例
单位时间内完成进程的数量
进程在就绪队列中等待的总时间
从提交请求到响应这个请求消耗的时间
常见的调度算法
谁先来谁先跑, 直到跑完 :短进程排在后面, 等10分钟跑1秒
短进程优先跑: 固定时间内能跑完最多的进程, 但你不知道谁短谁长
RR: 固定时间片还没结束就换人, 公平, 但如果时间片选太短, 那功夫全耗在进程切换上了, 时间片太长, 那就变成第一种非得等上一个人跑完我才能跑
不是说线程是调度的最小单位吗?
是的, 这里就是矛盾出现的地方, 他吗的讲到现在根本就没提过线程调度的事情, 实际上, schedule()函数在工作的时候就会根据算法, 面向的对象是一个叫task的结构体, 这个结构体里存的就是线程内容, 只不过这个线程可能跟你来自同一个进程, 也可能来自不同进程, 反正调度到谁谁就上来跑, 在切换的过程中就出现了我们常说的: 如果是同一个进程下的线程间相互切换, 代价小, 如果切换到另一个进程里的线程了, 那不好意思整个 寄存器 PCB都得切换
Last updated
Was this helpful?