# 简介

当一个程序需要执行多个任务时,主要有两种策略:

  • 只使用一个线程,串行执行。
  • 创建多进程或多线程,并行执行。

# 多进程

多进程(multiprocess)的优点:

  • 每个进程使用的内存、虚拟地址空间等资源相互独立,不会冲突。
  • 每个进程独立运行,一个进程挂掉了不会影响其它进程。

# 多线程

多线程(multithreading)的优点:

  • 与单线程相比,可以提高 CPU 的使用率。
    • 比如一个线程因为等待 IO 而暂停运行时,其它线程依然可以运行。
    • 比如一个线程占用了 CPU 的一个核时,其它线程可以在 CPU 的其它核上运行。
    • 处理 IO 密集型任务时,多进程、多线程可以提高 CPU 的使用率,从而提高处理速度。处理 CPU 密集型任务时,多进程、多线程不能提高处理速度。
  • 多线程相当于轻量级的多进程,开销更小。
    • 创建进程比创建线程的开销更大,需要重新分配系统资源。
    • CPU 切换进程时,不仅需要切换运行的线程,还需要切换进程所分配的内存、堆栈等资源。
  • 与进程间通信相比,线程间通信更容易。
    • 同一个进程的多个线程之间可以采用全局变量作为通信媒介,因为它们访问的是同一个堆区。

# 线程安全

  • 线程是 CPU 调度的基本单位。系统会决定由 CPU 的哪个核来执行线程、执行多长时间。

    • 创建多进程时,各个进程会按启动顺序,顺序执行。
    • 创建多线程时,各个线程的运行顺序无法预测。(因为负载变化时,CPU 的调度情况就可能变化)
  • 运行多线程时可能出现以下问题:

    • 一个线程在执行任务时,被其它线程打断。
      • 可以阻塞其它线程,先让该线程运行完该任务。
    • 一个线程在访问共享资源时,该资源被其它线程修改。
      • 可以给该资源上锁,保证同时只能被一个线程访问。

# 线程间通信

  • 线程间通信的常见方式:
    • 轮询(poll):主线程循环去检查子线程的状态,这会浪费一些主线程的时间,
    • 回调(callback):子线程执行结束后调用主线程的一个函数或方法。

# 并行与并发

  • 串行工作(Serial)
    • :一个程序同时只能执行一个任务,执行完之后才能执行下一个任务。
    • 例如每个线程都是串行工作的,同时只能顺序执行一段代码。
  • 并行工作(Parallel)
    • :一个程序同时执行多个任务。
    • 例如程序可以有多个线程,同时运行在多个 CPU 上。
  • 并发工作(Concurrent)
    • :一个程序同时处理多个任务,但不一定会同时执行。即上一个任务没有执行完,就可以处理下一个任务。
    • 例如程序可以有多个线程,交替运行运行在一个 CPU 上。