1. 进程与线程回顾

进程和线程是操作系统中最基础的概念之一。 通常来说,进程可以看作是一个正在运行的程序实例。每个进程都有独立的代码段和数据段,彼此之间互不干扰。也就是说,一个进程不会直接影响另一个进程的执行或数据资源。

线程则是一种轻量级的“半进程”,它必须依附于某个进程而存在。一个线程在进程的上下文中执行一个任务,技术上来说,线程需要与进程类似的资源,例如内存栈、程序计数器和寄存器集合,但这些资源是线程私有的。而同一个进程下的所有线程共享该进程的代码和数据段。

关于通信机制,进程分为独立进程协作进程两类:

  • 独立进程不与其他进程交互,也不受其他进程影响。
  • 协作进程在执行过程中需要与其他进程交换数据,由于进程之间是隔离的,因此它们之间的通信必须依赖进程间通信(IPC)机制

线程之间也存在通信需求,不过与进程不同的是,同一个进程下的线程可以直接通过进程的数据段进行通信,无需额外的通信机制。

下图简要展示了进程与线程之间的关系:

mm

总结:
尽管进程和线程是不同的执行单元,但它们关系密切。每个进程至少包含一个线程,而线程只能存在于某个进程中。

2. 多进程与多线程的基本概念

多进程和多线程分别用于实现多个进程和多个线程的并发执行,是操作系统实现多任务处理的核心机制。

2.1 多进程(Multiprocessing)

多进程指的是在一个系统中可以同时执行多个进程。
需要注意的是,真正的并行多进程执行要求系统具备多个物理处理器(CPU)或核心。这样不同的进程才能真正同时运行。

现实中,现代个人电脑通常配备两个或更多核心,支持多进程并行执行。例如,我们可以同时运行浏览器和文本编辑器,但系统中运行的进程数量通常远多于可用核心数,这时就需要操作系统进行时间片调度。

2.2 多线程(Multithreading)

多线程指的是一个进程内部可以并发执行多个不同任务。
多线程并不需要多个物理处理器。只要有一个处理器,就可以通过时间片分配实现多个线程的并发执行。

以文本编辑器为例:

  • 一个线程用于渲染图形界面
  • 一个线程用于监听用户输入
  • 一个线程负责自动保存文档
  • 其他后台线程负责拼写检查、自动补全等功能

这些线程共享处理器时间,虽然看起来“同时”运行,但本质上是操作系统通过调度轮流执行它们。

3. 技术实现细节

多进程和多线程的实现依赖于两个关键因素:硬件(处理器)操作系统(调度器)

3.1 硬件支持

  • 多进程需要多个物理处理器或核心
  • 多线程可以在单个处理器上实现并发执行(通过时间片轮转)
  • 现代处理器支持超线程(Hyper-Threading)技术,允许单个核心模拟多个逻辑处理器,提升并发性能

3.2 操作系统支持

操作系统是实现多任务处理的核心,其中两个关键组件是:

  • 调度器(Scheduler):决定哪个进程或线程在何时运行
  • 分派器(Dispatcher):负责切换上下文并分配处理器时间片

抢占式多任务系统(Preemptive Multitasking)中,当一个线程或进程的时间片用完后,操作系统会强制暂停其执行,切换到下一个任务。

此外,操作系统可以采用两种方式管理线程:

  • 内核级线程(Kernel Threads):由操作系统直接调度线程
  • 用户级线程(User Threads):由进程自己管理线程调度,操作系统只看到进程本身

3.3 影响性能的因素

以下因素会直接影响多进程和多线程的性能表现:

  • 物理 CPU 数量和逻辑核心数量(例如是否支持超线程)
  • 操作系统的调度策略(如优先级调度、公平调度等)
  • 对阻塞进程/线程的处理方式(如是否支持异步 I/O)
  • 线程间通信的效率(共享内存 vs IPC)

4. 总结

多进程和多线程虽然在实现机制上有所不同,但它们都服务于一个共同目标:提升系统并发性和资源利用率

区别总结:

特性 多进程 多线程
资源开销 大(每个进程独立内存空间) 小(共享进程内存)
通信机制 需要 IPC 共享内存直接通信
稳定性 一个进程崩溃不影响其他进程 同一进程中线程崩溃可能影响整个进程
并发性 需要多核支持 单核即可实现并发
适用场景 系统级并行任务 同一任务内部并发处理

⚠️ 踩坑提醒:

  • 多线程编程中容易遇到线程安全问题(如竞态条件、死锁),需谨慎使用同步机制(如 synchronized、Lock)
  • 多进程间通信成本高,不适合频繁交互的场景
  • Java 中线程是轻量级的,但也不能无节制创建,建议使用线程池管理

最终建议: 根据实际需求选择多进程或多线程方案,两者并非对立,而是互补。在实际开发中,往往结合使用,例如使用多进程隔离任务边界,再在每个进程中使用多线程提高并发效率。


原始标题:Multiprocessing and Multithreading