内核空间和用户空间

根据资源访问权限的不同,操作系统会把内存分为内核空间和用户空间,内核空间的指令代码具备直接调度计算机底层资源的能力,比如说I/O资源等;用户空间的代码没有访问计算机底层资源的能力,需要通过系统调用等方式切换为内核态来实现对计算机底层资源的申请和调度。

用户线程和内核线程

线程作为操作系统能够调度的最小单位,也分为用户线程和内核线程。
(1)用户线程由用户空间的代码创建、管理和销毁,线程的调度由用户空间的线程库完成(可能是编程语言层次的线程库),无需切换内核态,资源消耗少且高效。同一进程下创建的用户线程对CPU的竞争是以进程的维度参与的,这会导致进程下的用户线程只能分时复用进程被分配的CPU时间片,所以无法很好利用CPU多核运算的优势。我们一般情况下所说的线程其实是指用户线程。
(2)内核线程由操作系统管理和调度,能够直接操作计算机底层的资源,线程切换的时候CPU需要切换到内核态。它能够很好利用多核CPU计算的优势,开发人员可以通过系统调用的方式的使用内核线程。
用户线程是无法被操作系统感知的,用户线程所属的进程或者内核线程才能被操作直接调度,分配CPU的使用时间。对此衍生出了不同的线程模型,它们之间对CPU资源的使用各有利弊。

线程模型

用户级线程模型(多对一模型)

一个进程对应一个内核线程,如下图所示:

用户线程模型

优点:

  • 线程管理在用户空间执行,效率高
    缺点:
  • 进程内的多线程无法利用CPU多核运算的优势,只能通过分时复用的方式轮换执行。
  • 进程内的任意线程阻塞,导致整个进程被阻塞

内核级线程模型(一对一模型)

进程中的每个线程都会对应一个内核线程,如下图所示:
内核级线程模型
优点:

  • 能够充分利用CPU的多核并行计算能力,因为每个线程可以独立被操作系统调度分配到CPU上执行指令
  • 某个线程的阻塞并不会影响到进程内的其他线程工作的执行
    缺点:
  • 每次线程切换上下文时都会从用户态切换到内核态,产生有不小的资源消耗。
  • 创建线程的数量受限于操作系统内核可创建内核线程的数量

两级线程模型(多对多模型)

两级线程模型相当于用户级线程模型和内核级线程模型的结合,一个进程将会对应多个内核线程,由进程内的调度器决定进程内的线程如何与申请的内核线程对应,如下图所示:
两级线程模型
进程会预先申请一定数量的内核线程,然后将自身创建的线程与内核线程进行对应。用户线程的调用和管理由进程的调度器负责,而内核线程的调度和管理由操作系统负责。
该模型克服了以上其他模型的缺点,且保留了它们的优点。