进程、线程和协程

29 阅读3分钟

进程

计算机发展早期,只有进程这个概念,进程作为运行中程序的抽象,此时的进程既是资源分配的基本单位,又是CPU调度的基本单位
有了进程后,就可以满足计算机同时运行多个任务的诉求了,每个任务创建一个进程运行即可。

但是,随着计算机的发展,出现了如下诉求:一个程序运行时要同时运行多个任务。此时只能创建多个进程来解决,但有缺陷:

  1. 进程非常重量级,创建、销毁一个进程开销很大,性能不行。
  2. 进程之间共享数据很困难。

线程

于是,出现了线程的概念。

  • 线程是轻量级进程
  • 线程作为CPU调度的基本单位,而进程只作为资源调度的基本单位
  • 一个进程可以创建很多线程,这些线程共享进程的地址空间,所以线程间共享数据很简单

有了线程后,一个进程就能同时运行多个任务了,此时一个程序想运行多个任务只需要创建一个进程然后创建多个线程即可,且性能还非常高。

协程

  • 协程是轻量级线程,创建、销毁开销很小
  • 协程依赖线程执行,线程仍然是CPU调度的基本单位
  • 协程由用户程序自己实现,完全运行在用户空间,上下文切换时无需进行用户态和内核态的切换,开销很小

协程相比于线程:

  1. 更轻量,创建、销毁开销小
  2. 上下文切换开销小,无需进行用户态和内核态切换

没有协程时,一个线程同时只能执行一个任务,一个任务执行完才能执行下个任务
有了协程后,一个线程能并发执行多个任务,即协程让线程具有了并发执行多个任务的能力。(就像线程让进程能同时执行多个任务一样)。

有了协程后,并发能力更强了(一个线程也能并发执行多个任务了),并且协程非常轻量,创建、销毁开销很小,上下文切换时几乎没有开销,性能几乎不受影响。

例子:假如有100个任务,100个任务需要并发执行:

  1. 使用线程执行任务,就需要创建100个线程,线程的创建、销毁开销大,上下文切换开销也大,会影响性能
  2. 使用协程执行任务,可能只需要创建10个线程,每个线程再并发执行10个任务,协程的创建、销毁开销小,上下文切换开销也小,几乎不影响性能。

总结

任务执行单元或任务调度单元从进程到线程再到协程,越来越轻量(创建、销毁开销越来越小),并发度也越来越高。

协程依赖线程,线程依赖进程。

image.png

其实,运行一个程序很简单:
首先,把可执行程序(机器指令代码)和数据加载到内存;然后,CPU不断读取指令并解释指令,就能运行一个程序了。

进程到线程到协程的发展路径:

未命名文件.png