Linux进程线程的相关概念梳理

37次阅读

共计 1277 个字符,预计需要花费 4 分钟才能阅读完成。

Linux 的线程模型

自 Linux 诞生以来有三种

  1. LinuxThreads, 最早的模型, 只部分实现 POSIX Threads 标准
  2. NGPT, Next Generation POSIX Threads, 已终止
  3. NPTL, Native POSIX Thread Library, 从 2.6 内核以来到现在所使用的模型

在 NPTL 中, Linux 使用的用户线程与内核线程 1:1 内应的线程模型, 这也是众多其它系统, win32, Solaris, NetBSD, FreeBSD, macOS, iOS 等所采用的模型, 1:1 模型的实现相对 N:1 和 M:N 要简单些.

当调用 pthread 库创建的一个线程时, pthread_create会调用 clone 系统调用, 最终会创建一个 LWP(轻量级进程) 和一个内核线程. NPTL 的 1:1 模型,即 1 个轻量级线程对应 1 个内核线程. 此时该 LWP 在内核态有对应的 task_struct(进程描述符), 是一个独立的线程调度单元

Linux 的进程与线程

对于系统而言并不区分进程与线程, 创建进程与创建线程都是使用 fork 系统调用, 只是传参上的区别, 比如子进程会有自己的独立地址空间, 而线程则会共享空间. 内核进行调度的单位是 task.
可认为 Linux 里的线程本质上是共享资源的一系列进程.

LWP/ 用户线程 / 内核线程

LWP, Light-weight process, 即轻量级线程, 本质上来讲一种由内核支持的用户线程.
内核线程 , 只能访问内核空间, 共享相同的内核页表, 所有内核线程的内核空间是相同的, 而用户线程则是拥有自己的地址空间(与非同一进程的其它线程的空间不同).
用户线程, 标准意义上的用户线程应当是完全建立在用户空间的线程,用户线程的创建, 同步, 销毁, 调度完全在用户空间完成, 不需要内核的协助. 这个定义与 LWP 存在一定的交叉.

上下文切换

被抢占的 LWP, 需要在用户态保存当前寄存器, 然后切换到内核态, 保存对应内核线程的寄存器, 恢复调度时, 分别恢复这两个现场, 涉及至少两次的栈切换和一定程度的缓存失效.

Green threads

绿色线程, 由运行时库或虚拟机进行调度的 ” 线程 ”, 完全在用户空间进行管理.
Jdk1.2 之前, 在 Solaris 等平台上实现的线程模型, 类型上属于绿色线程. 早期的 Linux 线程模型也属于绿色线程.
另外常见属于此类型的实现主要是协程, 像 Java 中的 Quasar, Python 中的 Greenlet 等.

Coroutine

协程, 是为解决非抢占式多任务处理的泛化子例程, 本质上是一种程序控制机制. 协程可以有多个入口点,可以在指定位置挂起和恢复执行.
协程分为两类

  • 非对称式协程, 协程间有调用链关系, 有两种传递程序控制权的方式(resume/yield), 一个非对称协程可看做从属于它的调用者
  • 对称式协程, 只有一种传递程序控制权的操作(coroutine.transfer)

Fiber

基本上可认为是协程的一种实现

Java 创建的线程是什么线程

Java 1.2 以前有些是 Green threads.
1.2 以后, 以 Linux 平台为例, 线程的创建最终是调用到pthread_create, 是内核级线程

正文完
 0