进程、线程与协程

116 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情

多任务

在计算机物理层面上,如何执行多任务呢?有两种方式可以实现:提供多颗CPU,或者一颗CPU有多个核心。在应用端,我们倾向于后者,因为我们在乎的是产品做的更小;而在服务器端,可能两者兼有,我们更需要的是算力。

那如果只有一颗单核CPU,能实现多任务吗?

也可以。

以JavaScript语言来说,它就是单线程机制。在开发中,我们所感受到的多任务在同时进行其实是个假象。实际的底层运行原理是:把CPU的时间切成一段段小的时间片,每个时间片段只运行某一个执行体,这个时间片给执行体 A,下一个时间片给执行体B。因为时间片很小,我们会感觉这些程序同时都在运行,其实是在不断的切换。这种分时间片实现的多任务系统,我们把它叫分时系统

分时系统的原理说起来比较简单,把当前任务状态先保存起来,把另一个任务的状态恢复,并把执行权交给它,然后不断循环往复的进行。这里面涉及到几个问题:

  • 任务是什么,怎么抽象任务这样一个概念?
  • 任务的状态都有什么,怎么保存与恢复?
  • 什么时机会发生任务切换?

我们先来看第一个问题:任务是什么,怎么抽象任务这样一个概念?其实任务的抽象并不是唯一的。大部分操作系统提供了两套:进程和线程。有的操作系统还会提供第三套叫协程(也叫纤程),像Erlang和Go语言就提供了比较完善的协程库。

进程和线程

进程的出现是从操作系统安全角度来考虑的,是一个基本的隔离单位,不同进程之间基于最低授权的原则。早期操作系统中是没有线程的概念的,也不会有人想到要搞两套执行体。所以进程实际上就承担了一部分来自线程的需求。

之后线程的出现,是因为发现操作系统同一个软件内还是会有多任务的需求,这些任务处在相同的地址空间,彼此之间相互可以信任。

协程

其实对于常规的应用或服务器来说,进程和线程是完全够用的,那为什么又搞出个协程出来了呢?这完全是由于现在对服务器的高并发有越来越高的要求,也是实现高性能的网络服务器的需要。

我们来看下网络服务器的简单模型:

image.png

有一点需要注意的是:协程并不是操作系统内核提供的,它其实属于一种用户态线程。因为它是在用户态下实现的。