进程和线程
进程
进程是资源分配的基本单位。
进程控制块(PCB)描述进程基本信息和运行状态,创建进程和撤销进程。
线程
线程是CPU调度的基本单位。
一个进程可以有多个线程。他们共享进程资源。
QQ 和浏览器是两个进程,浏览器进程里面有很多线程,例如 HTTP 请求线程、事件响应线程、渲染线程等等,线程的并发执行使得在浏览器中点击一个新链接从而发起 HTTP 请求时,浏览器还可以响应用户的其它事件。
进程和线程的区别
资源方面
进程是资源分配的基本单位,但是线程不拥有资源,线程可以访问进程的资源。
调度方面
线程时独立调度的基本单位,在同一进程中,线程的切换不会引起进程切换。从一个进程中的线程切换到另一个进程的线程时,会引起进程的切换。
系统开销方面
创建和撤销进程时,系统都要为之分配或回收资源,如内存空间、I/O设备等,所带来的的开销远大于创建和撤销线程的开销。
另外,在进程切换时,涉及当前执行进程CPU环境的保存及新调度进程CPU环境的设置,但线程切换时,只需保存和设置少量子村器内容,开销很少。
通信方面
线程间可以通过直接读写同一进程中的数据进行通信,但是进程通信需要IPC
进程状态
- 就绪状态——等待被调度
- 运行状态——进程运行
- 阻塞状态——等待资源
- 只有就绪态和运行态可以相互转换,其他都是单向转换
- 就绪态的进程通过调度算法获得CPU的运行时间,转为运行态
- 运行态的进程,在分配给它的CPU时间片用完后会转为就绪状态
- 阻塞状态时缺少需要的资源从而有运行态转换而来,该资源不包括CPU时间,缺少CPU时间会从运行态转为就绪态
七态模型
七态模型在五态模型的基础上增加了挂起就绪态和挂起等待态。
- 挂起就绪态:进程具备运行条件,但目前在外存中,只有它被对换到内存才能被调度执行。
- 挂起等待态:表明进程正在等待某一个事件发生且在外存中。
进程进入挂起状态是由于操作系统、父进程或进程本身阻止它的运行。
线程状态
下图是Java线程的状态
- 初始状态:new一个实例,线程就进入了初始状态。
- 就绪状态:有运行的资格,调度程序还没挑选到该线程
- 运行状态:线程的run方法执行时
- 阻塞状态:线程阻塞进入synchronized关键字修饰方法或代码块时的状态。
- 等待状态:处于这种状态的线程不会被分配CPU执行时间,它们要等待被显式地唤醒。否则会处于无限期等待的状态。
- 超时状态:处于这种状态的线程不让出系统资源,无须无限期等待被其他线程显示地唤醒,在达到一定时间后它们会自动唤醒。
- 终止状态:run()方法完成时,就认为它终止了。
进程调度算法
不同环境调度方法不同。
批处理系统
批处理系统没有太多的用户操作,在该系统中,调度算法目标是保证吞吐量和周转时间。
先来先服务
非抢占式调度算法,按照请求的顺序进行调度。
有利于长作业,不利于短作业,因为短作业必须等待前面的长作业执行完毕才能执行。
短作业优先
非抢占式调度算法,按估计运行时间最短的顺序进行调度。
长作业可能饿死,处于一直等待短作业完毕的状态。
最短剩余时间优先
最短作业时间优先的抢占式版本,按照剩余运行时间的顺序进行调度。
当一个新作业到达时,其整个运行时间与当前进程的剩余时间作比较。如果新的进程需要的时间更少,则挂起当前进程,否则新的进程等待。
交互式系统
交互式系统有大量的用户交互操作,在该系统中调度算法的目标是快速地进行响应。
时间片轮转
所有就绪进程按到来的先后顺序排成一个队列。
每次调度时,把CPU时间分配给队首进程,该进程可以执行一个时间片。但时间片用完时,由计时器发出时钟中断,调度程序停止该进程的执行,并把它送至队列的末尾,同时继续把CPU时间分配给队首进程。
优先级调度
给每个进程分配一个优先级,按优先级进行调度。
为了防止低优先级继承永远得不到调度,可以随时间的推移增加等待进程的优先级。
多级反馈队列
一个进程需要执行100个时间片时,若采用时间片轮转算法,那么需要交换100次。
多级队列是为这种需要执行多个时间片的进程考虑,他设置了多个队列,每个队列时间片都不同。例如1 2 4 8…。进程在第一个队列没执行完会被移到下一个队列。
每个队列优先权不同,最上面的优先权最高。只有上一个队列没有进程在排队时,才能调度当前队列上的进程。