文章目录
2.1.5 线程概念与多线程模型
2.1.5.1 线程的来源
在很久以前还没有引入进程
之前,系统中的各个程序只能串行执行。比如你想要边听歌边开QQ,这是不可能做到的,只能先做一件事再做一件事。
后来引入进程后,系统中的各个程序可以并发执行。也就是说,可以同时听歌和开QQ。但是,即使引入了进程,也不能在QQ中同时视频聊天和传输文件。这是因为操作系统每一次执行都是按照进程为单位来执行的。
从上面的例子来看,进程是程序的一次执行。但是这些功能显然不可能是由一个程序顺序处理就能实现的。
有的进程可能需要“同时做很多事”,而传统的进程只能串行地执行一系列程序。为此,引入了线程
来提高并发度。
在传统中,进程是程序执行流的最小单位,也就是说,CPU每次执行任务,最少执行一个进程。而后在现在,CPU每次执行任务,最少执行一个线程,线程是进程的子集。也就是说,引入线程后,线程成为了程序执行流的最小单位。
综上所述,我们可以把线程理解为“轻量级进程”。线程
是一个基本的CPU执行单元
,也是程序执行流的最小单位
。引入线程之后,不仅是进程之间可以并发,进程内的各线程之间也可以并发,从而进一步提升了系统的并发度,使得一个进程内也可以并发处理各种任务(如QQ视频、文字聊天、传文件)。引入线程后,进程只作为除CPU之外的系统资源的分配单元(如打印机、内存地址空间等都是分配给进程的)。
2.1.5.2 线程机制带来的变化
资源分配、调度 | 并发性 | 系统开销 |
---|---|---|
传统进程机制中,进程是资源分配、调度的基本单位 | 传统进程机制中,只能进程间并发 | 传统的进程间并发,需要切换进程的运行环境,系统开销很大。 |
引入线程后,进程是资源分配的基本单位,线程是调度的基本单位 | 引入线程后,各线程间也能并发,提高了并发度 | 线程间并发,如果是同一进程内的线程切换,则不需要切换进程环境,系统开销小,也就是说引入线程后,并发所带来的系统开销减小。 |
切换进程环境的类比:
去图书馆看书。
切换进程运行环境 = 有一个不认识的人要用桌子,你需要把你的书(运行环境)收走,他把自己的书(运行环境)放到桌上。
同一进程内的线程切换 = 你的舍友要用到这张书桌,可以不把桌子上的书收走,因为大家彼此认识(属于同一个进程)。
2.1.5.3 线程的属性
2.1.5.4 线程的实现方式
用户级线程由应用程序通过线程库实现。所有的线程管理工作都由应用程序负责(包括线程切换)。用户级线程中,线程切换可以在用户态下即可完成,无需操作系统干预。在用户看来,是有多个线程;但是对于操作系统内核来说,并意识不到线程的存在。即用户级线程对用户不透明,对操作系统透明。
内核级线程(Kernel-Level Thread,KTL,又称为“内核支持的线程”)
内核级线程的管理工作由操作系统内核完成。线程调度、切换等工作都由内核负责,因此内核级线程的切换必然需要在核心态下才能完成。
在同时支持用户级线程和内核级线程的系统中,可采用两者组合的方式:将n个用户级线程映射到m个内核级线程上(n>=m)
需要重点关注的是:操作系统只“看得见”内核级线程,因此只有内核级线程才是处理机分配的单位
。
拿上面的映射图来说,该进程由两个内核级线程和三个用户级线程构成,在用户看来,这个进程中有三个线程。但即使该进程在一个4核处理机的计算机上运行,也最多只能被分配到两个核,最多只能有两个用户线程并行执行。
2.1.5.5 多线程模型
在同时支持用户级线程和内核级线程的系统中,由几个用户级线程映射到几个内核级线程的问题引出了“多线程模型”问题。
多对一模型
多个用户及线程映射到一个内核级线程。每个用户进程只对应一个内核级线程。
优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高。
缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行。
一对一模型
一个用户及线程映射到一个内核级线程。每个用户进程有与用户级线程同数量的内核级线程。
优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强,多线程可在多核处理机上并行执行。
缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。
多对多模型
n用户线程映射到m个内核级线程(n>=m)。每个用户进程对于m个内核级线程。
其克服了多对一模型和一对多模型的缺点。
2.1.5.6 小结
这一小节的知识点易作为选择题考查。