Python 到底是 线程快🚀 还是 进程快🚀
前言
在探究这个 Python 中 到底是 线程快 还是 进程快 前,有必要先了解一下CPython的GIL锁,这非常重要,关系到线程调用的机制,以及Python运行速度慢的原因之一
GIL全局解释器锁
GIL 全称 Global Interpreter Lock,中文释义 全局解释器锁,得先知道的是,这不是Python独有的特性,它只是在实现CPython(Python解释器)时,引入的一个概念
官方对此的描述
In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple
native threads from executing Python bytecodes at once. This lock is necessary mainly
because CPython’s memory management is not thread-safe. (However, since the GIL
exists, other features have grown to depend on the guarantees that it enforces.)
中文翻译
在CPython中,全局解释器锁或GIL是互斥锁,可防止多个
本地线程一次执行Python字节码。 这个锁主要是必要的
因为CPython的内存管理不是线程安全的。 (但是,自GIL
存在,其他功能也越来越依赖于它所执行的保证。)
简单的来说,就是在Cpython解释器中,同一个进程下开启多线程,由于GIL是一个互斥锁(mutex),阻止了多个线程在同一个进程内的同时执行,同一时刻的同一进程只能有一个线程在执行,毫无疑问,这降低了执行效率,那为什么还要有GIL的存在呢,要明白GIL的必要性,就需要了解CPython对于线程安全的 内存管理机制
线程快 还是 进程快 这得看应用场景,这里直接说答案,对于 计算密集型 的任务来说,多进程更快;对于 IO密集型 的任务来说,多线程更快
IO密集型
IO 是 Input/Output 的缩写,说白就是 对数据对读取和写入,那IO密集型,就是大部分在对数据 读取和写入 的程序系统(硬盘读写、网络传输等)
之前提到了由于 GIL全局解释器锁 的存在,同一时刻同一进程中只有一个线程在执行,对于这种想要等的IO操作来说,开再多的进程效果也不大,且开进程的开销较大,还不如多开线程,效率反而高点
性能测试
对于IO密集型程序来说,多线程下和多进程下的分别耗时统计
多进程
from multiprocessing import Process
class MyProcess(Process):
def sleep(self):
print(f"{self.name} 正在执行")
time.sleep(2)
def run(self) -> None:
self.sleep()
if __name__ == '__main__':
start_time = time.time()
pro_list = []
for i in range(10):
p = MyProcess()
p.start()
pro_list.append(p)
for i in pro_list:
i.join()
print(f"耗费时间: {time.time() - start_time}")
开启十个进程下,耗时为:2.734959363937378(每次运行不一样很正常,这里仅作参考)
多线程
from threading import Thread
class MyProcess(Thread):
def sleep(self):
print(f"{self.name} 正在执行")
time.sleep(2)
def run(self) -> None:
self.sleep()
if __name__ == '__main__':
start_time = time.time()
thr_list = []
for i in range(10):
t = MyProcess()
t.start()
thr_list.append(t)
for i in thr_list:
i.join()
print(f"耗费时间: {time.time() - start_time}")
开启十个线程下,耗时为:2.0112526416778564(每次运行不一样很正常,这里仅作参考)
计算密集型
程序系统大部分在做 数据计算、逻辑判断、循环等,为计算密集型,比如:1+2+3…+10000000
虽然说由于 GIL全局解释器锁 的存在,用不到真正的多线程,但可以开多进程呀,随着cpu的增多执行效率肯定会有所提高,但有种特殊情况是,然后电脑只有单核的情况下,没有多核来并行计算,徒增了创建进程的开销,多进程对单核来说不管用,不过话说回来,都已经这个时代了,单核的电脑我是没再见到过🤣
性能测试
对于计算密集型程序来说,多线程下和多进程下的分别耗时统计
多进程
class MyProcess(Process):
def sleep(self):
print(f"{self.name} 正在执行")
num = 0
while num < 10000000:
num += 1
def run(self) -> None:
self.sleep()
if __name__ == '__main__':
start_time = time.time()
pro_list = []
for i in range(10):
p = MyProcess()
p.start()
pro_list.append(p)
for i in pro_list:
i.join()
print(f"耗费时间: {time.time() - start_time}")
开启十个线程下,耗时为:1.843491792678833(每次运行不一样很正常,这里仅作参考)
多线程
class MyProcess(Thread):
def sleep(self):
print(f"{self.name} 正在执行")
num = 0
while num < 10000000:
num += 1
def run(self) -> None:
self.sleep()
if __name__ == '__main__':
start_time = time.time()
thr_list = []
for i in range(10):
t = MyProcess()
t.start()
thr_list.append(t)
for i in thr_list:
i.join()
print(f"耗费时间: {time.time() - start_time}")
开启十个线程下,耗时为:3.725153923034668(每次运行不一样很正常,这里仅作参考)