计算机操作系统-进程(4)线程、多线程模型

线程概念 多线程模型

  • 什么是线程 为什么要引入线程

在引入进程之前,系统中的各个程序只能串行执行,而在引入了进程滞后,程序可以并发地执行,但是如果一个程序中存在很多个功能,例如运行QQ,同时需要进行文字聊天、视频、传输文件,显然这三个功能均是属于QQ这个应用程序、这个进程下的,进程是程序的一次执行,但是这三个功能不可能是由一个程序按照顺序处理完成的,所以由此引入了线程

如何理解线程及其存在的意义

如果在没有引入线程,仅仅只有进程的情况下,一个程序对应一个进程,所以进程对应的就是这个程序的执行,那么就像是之前QQ的三个功能的例子,从用户的角度来看,在一个时间段内只能完成该程序的多个功能中的一个功能,并不能同时地执行多个功能。也可以理解为一个进程中只对应一份代码;而当引入线程时,在一个进程的内部可以存在多个线程,这些线程各自对应一份代码,这些代码可以相同,即完成相同的功能,也可以不同,即完成不同的功能。并且,这些在一个进程内的线程是可以并发执行的。也就是说,线程的引入,可以使得进程能够“同时”做很多事情,注意这个“同时”是宏观上的,即多个线程之间是可以并发运行的

所以,可以把线程理解为“轻量级进程”,或者是“进程中的进程”

由此可见传统的进程是程序执行流额最小单位。而在引入线程之后,线程成为了程序执行流的最小单位,是一个基本的CPU执行单元

为什么要引入线程

引入线程之后,不仅仅是进程之间可以并发,进程内的各个线程之间同样也可以并发,从而进一步提高了系统的并发度,使得一个进程内也可以并发处理各种任务

引入线程之后,进程只作为除CPU之外的系统资源的分配单元,例如打印机、内存地址空间等都是分配给进程的。而CPU则是分配给线程的。因为线程是程序执行流的最小单位,是一个基本的CPU执行单元

  • 引入了线程机制后发生了哪些变化

1.资源分配、调度

  • 传统进程机制中,进程是资源分配、调度的基本单位
  • 引入线程后,进程是资源分配的基本单位,线程是调度的基本单位

2.并发性

  • 传统进程机制中,只能进程间并发
  • 引入线程后,各个线程之间也能并发

3.系统开销

  • 传统的进程间并发,需要切换进程的运行环境,系统开销很大
  • 线程间并发,如果是同一进程内的线程切换,这不需要切换进程环境,系统开销小,所以引入线程后,并发所带来的系统开销减小

如何理解线程间切换带来的系统开销小:

因为引入线程之后,系统资源是分配给进程的,而CPU是分配给线程的,所以除了CPU之外所需要的东西都在进程中,而同一个进程内线程相当于共享了这个进程,也就是共享了这个进程间的资源,所以在进程内的线程间的切换,并不需要切换进程环境,因为所需要的系统资源都在同一个进程内,所以系统开销小。

  • 线程的属性

  1.  线程是处理机调度的单位
  2. 多CPU计算机中,各个线程可以占用不同的CPU:因为线程是处理机调度的单位
  3. 每个线程都有一个线程ID、线程控制块TCB:类比没有引入线程的进程的进程ID和进程控制块PCB
  4. 线程也有运行、就绪、阻塞三种基本状态
  5. 线程几乎不拥有系统资源:出了CPU外的系统资源都被分配给了进程,包括一些IO设备、内存地址空间等等
  6. 同一进程的不同线程共享进程的资源
  7. 由于共享内存地址空间,同一进程中的线程间的通信甚至无需系统干预
  8. 同一进程中的线程切换,不会引起进程切换,但是不同进程中的线程切换,则会引起进程切换
  9. 切换同一进程中的线程,系统的开销小;而切换不同进程中的线程,系统的开销较大
  • 线程的实现方式

线程的实现方式有两种:用户级线程和内核级线程

用户级线程User-Level Thread,ULT

用户级线程是由应用程序通过线程库实现的。所有的线程管理工作都由应用程序负责,包括线程的切换。所以在用户级线程中,线程切换在用户态下即可完成,无需操作系统干预。

在用户看来,该进程是有多个线程的。但是在操作系统内核看来,并意识不到线程的存在。即用户级线程对用户不透明,对操作系统透明。所以对于用户级线程,进程才是调度的基本单位,而不是线程。这就相当于把处理器分配给进程,而这个处理器具体是如何分配给进程中的线程,这就是由应用程序或者说用户自己决定的,和操作系统再无关系。

所以可以说,“用户级线程”就是“从用户视角看得到的线程”

内核级线程Kernel-Level Thread,KLT,又可称为内核支持的线程

内核级线程的管理工作由操作系统内核完成。线程的调度、切换等工作都是由内核负责,因此内核级线程的切换必然要在核心态下才能完成。

所以此线程实现方式下,线程是调度的基本单位,而不是进程。对于操作系统来说,是要把处理器分配给线程,而不是进程的。换言之,处理器具体分配个进程中的哪个线程,是由操作系统决定的。这也就说明了,此时线程对于操作系统来说是不透明的,同样对于应用程序,或者是用户来说,线程也是不透明的。

所以可以说,“内核级线程”就是“从操作系统内核视角看得到的线程”

注意,对“**级线程”就是“从**视角看得到的线程”的理解。即使是在内核级线程的实现方式下,若是从用户的视角去看,也是有用户级线程的。在内核级线程的线程实现方式下,用户级线程和内核级线程个数是一致的。

两种方式的组合

在同时支持用户级线程和内核级线程的系统中,可以采用二者组合的方式:将n个用户级线程映射到m个内核级线程上(n >= m)。

注意

在这种组合方式的情况下,操作系统只看得见内核级线程,因此只有内核级线程才是处理机分配的单位。例如当m=2, n=3时,即该进程由2个内核级线程(从操作系统的角度)和3个用户级内核(从应用程序的角度),假设在一个4核处理机的计算机上运行时,该进程最多也只能分配到2个核,也最多只有2个用户级线程并行执行,剩下1个用户级线程是并发执行。

这里m=2, n=3其实不太好理解。实际上运行一个程序的任务个数是从用户的角度上看的,所以n=3才是用户感受到的执行的任务个数。而m=2是从操作系统的角度看的线程数,或者说是任务数。

  • 多线程模型

在同时支持用户级线程和内核级线程的系统中(注意这是前提),由几个用户级线程映射到几个内核级线程的问题引出了“多线程模型的问题”

多对一模型

多个用户级线程映射到一个内核级线程。每个用户进程只对应一个内核级线程

  • 优点:用户级线程的切换在用户空间即可完成,并不需要切换到核心态,线程管理的系统开销小,效率高。这和只有用户级线程很相似。
  • 缺点:当一个用户线程被阻塞时,整个进程都会被阻塞,并发度不高,因为只有一个内核级线程,所以只被分配到一个单核处理器或者是多核处理器中的一核。此时多个线程不可以在多核处理机上并行运行。

一对一模型

一对一模型实际上就是纯粹的内核级线程模型。一个用户级线程映射到一个内核级线程。每个用户进程有与用户级线程同样数量的内核级线程

  • 优点:当一个线程被阻塞时,别的线程还可以继续执行,并发能力强。多线程可以在多核处理机上并行执行
  • 缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大

多对多模型

多对多模型实际上就是前面提到的组合型线程实现方式。n个用户及线程映射到m个内核级线程(n >= m)。每个用户进程对应m个内核级线程。

该模型克服了多对一模型并发度不高的缺点,有克服了一对一模型中一个用户进程占用太多内核级线程,开销太大的缺点。

注意

虽然用户级线程和内核级线程都可以理解为从不同的角度看到的线程,但是注意,这两种线程并不是同一个东西,即虽然从两个角度去看,但是看的对象并不是同一个。

猜你喜欢

转载自blog.csdn.net/weixin_39721347/article/details/86499938