线程是什么?

线程是抽象概念,因为Linux中内部没有专门为线程定义的数据结构和调度算法,Linux去实现“线程”的方式是“轻量级线程”,其本质还是进程。
定义:线程是操作系统能够调度和执行的基本单位,线程的本质是一个进程内部的一个控制序列,它是进程里面的东西,一个进程可以拥有一个进程或者多个进程。
同一个进程内多个线程之间可以共享代码段、数据段、打开的文件等资源,但每个线程各自都有一套独立的寄存器和栈,这样可以确保线程的控制流是相对独立的。
image.png

线程切换

线程的切换只有指令的切换,同处于一个进程里面,不存在映射表的切换。
而进程的切换就是在线程切换的基础上+映射表的切换。
image.png

线程的实现

主要有三种线程的实现方式:

  • 用户线程(User Thread):在用户空间实现的线程,不是由内核管理的线程,是由用户态的线程库来完成线程的管理;
  • 内核线程(Kernel Thread):在内核中实现的线程,是由内核管理的线程;
  • 轻量级进程(LightWeight Process):在内核中来支持用户线程;

用户线程

用户线程的整个线程管理和调度,操作系统是不直接参与的,而是由用户级线程库函数来完成线程的管理,包括线程的创建、终止、同步和调度等。
image.png

用户线程的优点:

  • 每个进程都需要有它私有的线程控制块(TCB)列表,用来跟踪记录它各个线程状态信息(PC、栈指针、寄存器)
  • 用户线程的切换也是由线程库函数来完成的,无需涉及内核态的切换,所以速度特别快;

用户线程的缺点:

  • 由于操作系统不参与线程的调度,如果一个线程发起了系统调用而阻塞(IO调用之类的),那进程所包含的用户线程都不能执行了。
  • 当一个线程开始运行后,除非它主动地交出 CPU 的使用权,否则它所在的进程当中的其他线程无法运行,打断一个线程执行只能由操作系统来做。

内核线程

内核线程是由操作系统管理的,线程对应的 TCB 自然是放在操作系统里的,这样线程的创建、终止和管理都是由操作系统负责。
image.png

内核线程的优点

  • 在一个进程当中,如果某个内核线程被阻塞,并不会影响其他内核线程的运行;
  • 分配给线程,多线程的进程获得更多的 CPU 运行时间;
  • 内核线程是多核处理机分配的单位

内核线程的缺点

  • 在支持内核线程的操作系统中,由内核来维护进程和线程的上下文信息,如 PCB 和 TCB;
  • 线程的创建、终止和切换都是通过系统调用的方式来进行,因此对于系统来说,系统开销比较大;

轻量级线程

轻量级进程(Light-weight process,LWP)是内核支持的用户线程,一个进程可有一个或多个 LWP,每个 LWP 是跟内核线程一对一映射的
image.png

多线程模型

在同时支持用户级线程和内核级线程的系统中,由几个用户级线程映射到几个内核级线程的问题引出了“多线程模型”问题。(具有一对一、多对一、多对多)

一对一

image.png

  • UT=用户线程;LWP=轻量级进程;KLT=内核线程

优点:每个线程都是独立的调度单元,直接利用操作系统内核提供的调度功能。
缺点:用户线程的阻塞唤醒,会直接映射到内核线程上,容易引起频繁切换,降低性能。

多对一

image.png
优点:提升并发量上限,大部分调度和同步操作都在用户空间内完成,减少状态切换,能够提升性能。
缺点:当一个用户线程进行了内核调用并阻塞了,那么其他线程在这段时间里都无法进行内核调用。

多对多

image.png

  • 集二者之长