
文章插图
那么为什么需要多线程?
- 许多应用同时发生着多种活动,其中一些活动会被阻塞,将进程进一步分解为多个线程,可以更灵活地处理各种类型的活动 。
- 线程更加轻量级,创建和终止速度更快,且线程之间切换的速度会比进程切换更快 。
- 对于一些 I/O 密集型任务,多个线程允许这些并排执行,加快整体的速度 。对于CPU密集型任务多线程没这个优势,因为本质上CPU同一时间只做一件事(什么是CPU密集型、I/O密集型?) 。
- 线程间通信的效率会高于进程间通信 。一般进程间通信需要内核介入,而同一进程内的线程间共享该进程的内存和文件,不需要调用内核就可以实现通信 。

文章插图
上图为多线程进程模型,其中线程控制块,也被称为TCB(Thread Control Block) 。
对于进程来说,进程 = 线程+资源 。
我们一开始提及过,操作系统底层存在调度程序,调度程序可调度任务,而单线程进程,每个进程可以对应一个任务 。现在,对于多线程的进程,每一个线程最终对于调度程序来说,都是一个任务,如下图(linux系统) 。因此也有一种流行的说法“线程是CPU调度的基本单位”

文章插图
3.2 线程状态和进程状态模型类似,线程的状态也有新建,运行,就绪,阻塞,终止 。与进程状态相似,终止线程时将进入终止状态 。但是区别于进程的是当一个进程被终止了,其内部的所有线程都会被终止 。由于线程之间的并行关系,同一进程内,一个线程被阻塞了,不会影响到其他线程 。
4.进程调度处理器调度,按照相对时间长短,可以分为长程调度,中程调度,短程调度 。(常见调度还有I/O调度,但不属于处理器调度) 。几种调度和进程的状态转换关系如下图

文章插图
4.1 几种调度方式4.1.1 长程调度长程调度又称为高级调度,作业调度 。
它控制系统的并发度,决定着哪一个批处理作业或者用户程序可以进入系统中处理,一旦运行进入,批处理作业或者用户程序就会变成进程,进入就绪队列 。
4.1.2 中程调度中程调度又称交换调度,中级调度 。
核心思想是将进程从内存或CPU竞争中移出,之后进程能重新被调入内存,通过这种方式可控制内存中进程数量 。如图中,从就绪队列中挂起的进程进入就绪挂起队列,从阻塞队列中挂起的进程进入阻塞挂起队列 。就绪挂起队列中的进程激活,则进入就绪队列 。
4.1.3 短程调度短程调度又称为低级调度,大部分时候讲的进程调度都是特指短程调度,短程调度将就绪队列中的进程调度到CPU中执行 。其中按照一定策略将CPU分配给一个就绪状态的进程,分为抢占式调度和非抢占式调度 。
非抢占式调度:
非抢占式调度,就是挑选一个进程,将CPU分配给它,该进程一直运行到终止或者因为等待事件进入阻塞状态(图中红字标注) 。显然这种调度方式存在一个硬伤:正在运行的进程如果需要运行很长时间,那么排在它后面的进程,只能一直等,直到它结束或阻塞 。
抢占式调度:
抢占式调度就是允许进程执行到一半时,将进程停下,CPU分配给其它进程 。
4.2 进程调度算法【一文详解操作系统进程管理】常见的进程调度算法有:
- 先来先服服务
- 时间片轮转
- 最短作业优先
- 最短剩余时间优先
- 优先级调度
- 多级反馈队列调度
4.2.1 先来先服务先来先服务(First Come First Serverd, FCFS) 。先进就绪队列,则先被调度,先来先服务是最简单的调度算法 。

文章插图
先来先服务存在上面谈论过的问题:当前面任务耗费很长时间执行,那么后面的任务即使只需要执行很短的时间,也必须一直等待 。属于非抢占式
4.2.2 时间片轮转调度时间片轮转调度,即上面第一章所描述的方式 。
每一个进程会被分配一个时间片,表示允许该进程在这个时间段运行,如果时间结束了,进程还没运行完毕,那么会通过抢占式调度,将CPU分配给其他进程,该进程回到就绪队列 。这是一种最简单最公平的调度算法,但是有可能会存在问题 。由于进程的切换,需要耗费时间,如果时间片太短,频繁进行切换,会影响效率 。如果进程时间片太长,有可能导致排后面的进程等待太长时间 。因此时间片的长度,需要有大致合理的数值 。(《现代操作系统》的观点是建议时间片长度在20ms~50ms) 。
推荐阅读
- 谈恋爱的技巧的方法详解
- CAN总线协议详解
- 腾讯云服务器操作系统TencentOS安装与体验
- 数据中台到底包括什么内容?一文详解架构设计与组成
- 一文让你搞懂MYSQL底层原理。-内部结构、索引、锁、集群
- 详解三种不同的身份验证协议
- 详解飞书新功能,如何让开发者“爽”起来?
- java中常见的六种线程池详解
- 一文读懂响应式编程到底是什么?
- linux网络编程常见API详解
