简单聊聊进程、线程、协程
要成为一个优秀的软件工程师,进程(process)、线程(thread)是一定要搞懂与掌握的知识点,不仅是因为它们是电脑科学根本的知识,更是因为懂得在适当的时机善用它们,可以增进程序的执行效率,也就是提升性能。
程序 Program
在了解进程与线程之前,得先谈谈 program 这个东西,其实所谓的 program 就是工程师编写的代码的集合,程序经过编译器或解释器处理后,被转化为机器可以理解和执行的形式。
进程 Process
Process 进程则是指被执行且载入内存的 program。 Process 也是 OS 分配资源的最小单位,可以从 OS 得到如 CPU Time、Memory…等资源,意思是这个 process 在运行时会消耗多少 CPU 与内存。下面是 MacOS 活动监视器的截图,相信不管是使用哪种操作系统的读者都有看过类似的界面,而监视器中列出的是你的电脑正在执行的应用程序,而它们其实就是一个个 process,可以从图片中看出每一个 process 消耗的 CPU、CPU 时间与每个 process 的独立 ID (PID)。

进程的优缺点与小结
- 优点:每个进程有自己独立的系统资源分配空间,不同进程之间的资源不共享,因此不需要特别对进程做互斥操作的处理。
- 缺点:建立进程以及进程的上下文切换(Context Switch)都较消耗资源,进程间若有通信的需求也较为复杂。
小结:程序 (Program)是写好尚未执行的代码,程序被执行后才会变成进程 (Process)。
线程 Thread
线程可以想像成存在于 process 里面,而一个进程里至少会有一个线程,前面有说 process 是 OS 分配资源的最小单位,而 thread 则是操作系统能够进行调度的最小单位,也就是说实际执行任务的并不是进程,而是进程中的线程,一个进程有可能有多个线程,其中多个线程可以共用进程的系统资源,可以把进程比喻为一个工厂,线程则是工厂里面的工人,负责任务的实际执行。
MultiProcessing 多进程 & MultiThreading 多线程
这两个概念我想继续利用工厂与工人的比喻会比较好理解与记忆。
Multiprocessing 好比建立许多工厂(通常会取 CPU 的数量),每个工厂中会分配ㄧ名员工(thread)执行工作,因此优势在于同一时间内可以完成较多的事。
Multithreading 则是将许多员工聚集到同一个工厂内,它的优势则是 有机会让相同的工作在比较短的时间内完成。
多线程的 Race Condition
刚刚有提到在多执行绪中 (Multithreading),不同 thread 是可以共享资源的,而若两个 thread 若同时存取或改变全局变量,可能会发生同步 (Synchronization) 问题。若执行期间互抢资源,则可能产生死锁 (Deadlock),因此使用多线程时必须特别注意避免这些状况发生。
Concurrent & Parallel 并发与并行

这两个是许多人容易误解的概念,然而透过上面的图就可以一目了然,Parallel 并行是利用多个 CPU 达到同时并行处理任务的需求(也就是同一个时间点有许多任务在同时执行),Concurrent 则是许多任务在争抢同一个 CPU 的资源,因此一个时间点只会有一个任务正在执行,只是因为切换非常快,使用者通常不会感觉到任务实际上一直在切换。
协程 Coroutine
协程是一种用户态的轻量级执行线程,协程的调度完全由使用者控制。

可以想像进程中有线程,而线程中则又有协程。而协程的调度完全由用户控制 ,协程也会有自己的 registers、context、stack 等等,并且由协程的调度器来控制目前由哪个协程执行,哪个协程要被 block 。process 及 thread 的调度,是由 CPU 内核去进行调度,而协程却不ㄧ样,OS 甚至不知道协程的存在,如果 coroutine 被卡住,则会在用户端直接切换另外一个 coroutine 给此 thread 继续执行,这样其他 coroutine 就不会被 block 住,让资源能够有效的被利用,借此实现 Concurrent 的概念。
相较于建立一个线程需要花费 MB 等级的内存,建立一个协程可以压到 KB 等级,协程间的切换也绝对快于线程间的切换。
小结
通过这篇文章讲了进程、线程、协程的概念,然而实际上要使用多进程、多线程开发时要考虑的因素真的很多,一不小心可能会造成上面提过的 race condition
或是性能不升反降的囧境,因此在使用上仍须经过谨慎考虑与实践验证的。