这个老生常谈了,但是,也可以瞅瞅。
多进程编程和多钱程编程,都可以使用并行机制来提升系统的运行效率。二者的区别在于运行时所占的内存分布不同。
- 多钱程是共用一套内存的代码块区间
- 多进程是各用一套独立的内存区间
多线程共享内存
1 | from threading import Thread |
输出
1 | 27409 1 |
多进程独立内存
1 | from multiprocessing import Process |
输出
1 | 26795 1 |
多进程的优点是稳定性好,一个子进程崩溃了,不会影响主进程以及其余进程。基于这个特性,常常会用多进程来实现守护服务器的功能。
多进程编程也有不足,即创建进程的代价非常大,因为操作系统要给每个进程分配固定的资源,并且操作系统对进程的总数会有一定的限制,若进程过多,操作系统调度都会存在问题,会造成假死状态。
多线程编程的优点是效率较高一些,适用于批处理任务等功能;不足之处在于,任何一个线程崩溃都可能造成整个进程的崩溃,因为它们共享了进程的内存资源池。
既然多线程编程和多进程编程各有优缺点,因此它们分别适用于不同的场景。比如说,对于计算密集型的任务,多进程效率会更高一下;而对于IO密集型的任务(比如文件操作,网络爬虫),采用多线程编程效率更高。为什么是这样呢?
其实也不难理解。对于 IO 密集型操作,大部分消耗时间其实是等待时间,在等待时间中,Python会释放GIL供新的线程使用,实现了线程间的切换;相反对于 CPU 密集型代码,2 个 CPU 干活肯定比一个 CPU 快很多。
在大型的计算机集群系统中,通常都会将多进程程序分布运行在不同的计算机上协同工作。而每一台计算机上的进程内部,又会由多个线程来并行工作。
注意,对于任务数来说,无论是多进程编程或者多线程编程,其进程数或线程数都不能太多:
对于多进程编程来说,操作系统在切换任务时,会有一系列的保护现场措施,这要花费相当多的系统资源,若任务过多,则大部分资源都被用做干这些了,结果就是所有任务都做不好;
多线程编程也不是线程个数越多效率越高,通过下面的公式可以计算出线程数量最优的一个参考值。
$$ 最佳线程数量 = \frac{线程等待时间 + 线程CPU时间}{线程CPU时间} \ast {CPU 数量} $$
- 同一时刻一个进程只能运行一个线程,无论多少个 CPU
- 想要利用多 CPU 只能利用 「多进程」