# 简介
当一个程序需要执行多个任务时,主要有两种策略:
- 只使用一个线程,串行执行。
- 创建多进程或多线程,并行执行。
# 多进程
多进程(multiprocess)的优点:
- 每个进程使用的内存、虚拟地址空间等资源相互独立,不会冲突。
- 每个进程独立运行,一个进程挂掉了不会影响其它进程。
# 多线程
多线程(multithreading)的优点:
- 与单线程相比,可以提高 CPU 的使用率。
- 比如一个线程因为等待 IO 而暂停运行时,其它线程依然可以运行。
- 比如一个线程占用了 CPU 的一个核时,其它线程可以在 CPU 的其它核上运行。
- 处理 IO 密集型任务时,多线程、多进程都可以提高 CPU 的使用率,从而提高处理速度。处理 CPU 密集型任务时,多线程、多进程都不能提高处理速度。
- 多线程相当于轻量级的多进程,开销更小。
- 创建进程比创建线程的开销更大,需要重新分配系统资源。
- CPU 切换进程时,不仅需要切换运行的线程,还需要切换进程所分配的内存、堆栈等资源。
- 与进程间通信相比,线程间通信更容易。
- 同一个进程的多个线程之间可以采用全局变量作为通信媒介,因为它们访问的是同一个堆区。
# 线程安全
线程是 CPU 调度的基本单位。系统会决定由 CPU 的哪个核来执行线程、执行多长时间。
- 创建多进程时,各个进程会按启动顺序,顺序执行。
- 创建多线程时,各个线程的运行顺序无法预测。(因为负载变化时,CPU 的调度情况就可能变化)
运行多线程时可能出现以下问题:
- 一个线程在执行任务时,被其它线程打断。
- 可以阻塞其它线程,先让该线程运行完该任务。
- 一个线程在访问共享资源时,该资源被其它线程修改。
- 可以给该资源上锁,保证同时只能被一个线程访问。
- 一个线程在执行任务时,被其它线程打断。
# 线程间通信
- 线程间通信的常见方式:
- 轮询(poll):主线程循环去检查子线程的状态,这会浪费一些主线程的时间,
- 回调(callback):子线程执行结束后调用主线程的一个函数或方法。
# 并行与并发
- 串行工作(Serial)
- :一个程序同时只能执行一个任务,执行完之后才能执行下一个任务。
- 例如每个线程都是串行工作的,同时只能顺序执行一段代码。
- 并行工作(Parallel)
- :一个程序同时执行多个任务。
- 例如程序可以有多个线程,同时运行在多个 CPU 上。
- 并发工作(Concurrent)
- :一个程序同时处理多个任务,但不一定会同时执行。即上一个任务没有执行完,就可以处理下一个任务。
- 例如程序可以有多个线程,交替运行运行在一个 CPU 上。