参考:https://juejin.im/post/5e3a16e06fb9a07ccb7e8472

进程与线程区别:

  • 进程是资源分配的基本单位
  • 进程有用独立的地址空间
  • 线程只是一个进程中不同的执行路径
  • 线程是 CPU 调度的基本单位
  • 线程有自己的堆栈和局部变量,但没有单独的地址空间
  • 一个进程下可能有多个线程
  • 线程共享进程的资源

在 Linux 中,线程对应的是轻量级进程。

并发与并行:

  • 并发的关键是,处理多个任务的能力,但不一定要同时
    • 比如单核多线程,基于 CPU 分片。但同一时间只有一个线程在运行
  • 并行的关键是,同时处理多个任务的能力
    • 比如多核 CPU,每个核心都能同时运行

协程:

协程 Coroutine:用户态线程,需要用代码编写一套线程调度器。协程对于系统而言是无感知的。
与线程的区别:线程需要由内核调度,而协程则由程序自己调度。

Go 协程:

Goroutine:Go 语言在语言层面对协程进行的原生支持
CSP 并发模型是通过 Goroutine 和 Channel 来实现的

注意:Goroutine 只是表示一个在协程中运行的任务,而 Go 协程是由并发模型等共同组成的。(可能)

Go 调度器采用 GPM 模型
涉及到的几个概念:

进程、线程、协程 - 图1

新创建的 Goroutine 会放入 Global 全局运行队列中,等待 Go 调度器进行调度。 随后 Goroutine 会被分配给其中一个逻辑处理器 P,并放入对应的 Local 本地运行队列中。 最终等待被逻辑处理器 P 执行即可。 当 P 对应的 Local 队列没有任务时,它会尝试从其他 Local 队列中窃取任务。

进程、线程、协程 - 图2

进程、线程、协程 - 图3

Goroutine 的状态:
进程、线程、协程 - 图4
Gsyscall:
Gwaiting:
Gcopystack:

状态图:
进程、线程、协程 - 图5