跳转至

拆解执行

基本介绍§

程序是一组静态存在的指令集合,本身并不会运行。它由程序员编写并保存在磁盘中,只有被操作系统加载之后,才有可能真正参与执行。从这个角度看,程序更像是一份说明书,而不是正在运转的实体。

当程序被加载到内存并开始执行时,就形成了进程。进程是操作系统中资源分配和隔离的基本单位,拥有独立的地址空间和系统资源。正因为这种隔离性,一个进程的异常通常不会直接影响其他进程。

进程内部可以包含一个或多个线程,进程提供运行环境,而具体的执行由线程完成。

线程是进程内真正的执行单元。同一进程中的多个线程共享内存和资源,这使得线程之间的通信成本很低,也让它们比进程更加轻量。操作系统会对线程进行调度,使多个线程在时间片内交替执行。

共享资源带来了效率,也引入了风险。若缺乏合理的同步机制,线程之间容易产生竞争条件和死锁,这是多线程编程复杂度的主要来源。

协程是一种更轻量的并发机制。与线程不同,协程不依赖操作系统调度,而是由程序在合适的位置主动挂起和恢复执行。这种用户态切换几乎没有上下文切换开销。

协程通常用于异步编程,尤其适合 I/O 密集型场景。它可以在单线程内实现高并发逻辑,从而避免多线程带来的同步复杂性,例如 Python 中的 async / await 机制。

---
config:
    treemap:
        showValues: false
---
treemap-beta
"程序"
    "进程1"
        "线程1"
            "协程1": 90
            "...": 10
        "...": 20
    "...": 20

各自的优缺点§

程序结构清晰、语义直接,易于理解和维护,也不依赖特定的并发模型。但程序本身只有单一执行流,无法直接利用多核处理器的能力,一旦需要并发处理任务,就必须引入进程或线程。

进程通过内存隔离换取了稳定性和安全性,一个进程的崩溃通常不会波及其他进程。然而,这种隔离也带来了较高的开销,进程的创建、销毁以及上下文切换成本较大,进程间通信依赖 IPC,设计复杂度较高。

线程在资源消耗上更加轻量,能够高效共享数据并发挥多核 CPU 的并行能力。但共享内存也使得线程更容易出错,竞争条件和死锁问题增加了调试和维护的难度。

协程进一步降低了并发成本,切换开销极小,适合高并发的 I/O 场景。它还能让异步逻辑以接近同步的方式表达,提升代码可读性。不过,协程通常运行在单线程内,无法直接利用多核性能,并且依赖语言或框架的支持。

它们之间的关系§

从层级上看,程序是静态的,进程是程序运行后的实例;进程为线程提供资源和隔离环境,而线程是操作系统调度的基本执行单位;协程则运行在线程之内,由程序自行控制调度。

进程彼此独立,线程共享进程资源,协程共享线程执行上下文。进程和线程的切换由操作系统完成,而协程的切换完全发生在用户态。

在实际应用中,进程和线程更适合 CPU 密集型任务,而协程通常用于 I/O 密集型场景,通过减少阻塞和切换成本提升整体效率。

评论