Python多进程与多线程适用场景及性能对比分析
本文通过64核CPU环境下的实测代码,对比Python多进程与多线程在计算密集型和IO密集型任务中的性能差异。结果显示,多进程能有效利用多核CPU提升计算效率,而受GIL限制的多线程在IO阻塞场景中表现更优。同时提供了处理文件打开数超限错误的解决方案。
前言
在Python并发编程中,多进程主要适用于计算密集型任务。
多线程则更适合处理IO密集型任务。
计算密集型任务通常涉及大量的逻辑运算,例如进行上亿次的加减乘除操作。在此类场景下,利用多核CPU进行并发处理可以显著提升计算性能。
IO密集型任务主要涉及输入输出操作,如文件读取或网络请求。这类场景常遇到IO阻塞,即使使用多核CPU执行,性能提升也较为有限。
接下来,我们将使用一台64核的虚拟机,通过具体的示例代码来展示两者的区别。
示例1:执行计算密集型任务,进行1亿次运算
使用多进程
from multiprocessing import Process
import os, time
# 计算密集型任务
def work():
res = 0
for i in range(100 * 100 * 100 * 100): # 亿次运算
res *= i
if __name__ == "__main__":
l = []
print("本机为", os.cpu_count(), "核 CPU") # 本机为64核
start = time.time()
for i in range(4):
p = Process(target=work) # 多进程
l.append(p)
p.start()
for p in l:
p.join()
stop = time.time()
print("计算密集型任务,多进程耗时 %s" % (stop - start))
使用多线程
from threading import Thread
import os, time
# 计算密集型任务
def work():
res = 0
for i in range(100 * 100 * 100 * 100): # 亿次运算
res *= i
if __name__ == "__main__":
l = []
print("本机为", os.cpu_count(), "核 CPU") # 本机为64核
start = time.time()
for i in range(4):
p = Thread(target=work) # 多线程
l.append(p)
p.start()
for p in l:
p.join()
stop = time.time()
print("计算密集型任务,多线程耗时 %s" % (stop - start))
两段代码的输出结果如下:
本机为 64 核 CPU 计算密集型任务,多进程耗时 6.864224672317505 本机为 64 核 CPU 计算密集型任务,多线程耗时 37.91042113304138
说明:上述代码中,分别使用4个多进程和4个多线程去执行亿次运算,多进程耗时6.86s,多线程耗时37.91s,可见在计算密集型任务场景,使用多进程能大大提高效率。
另外,当分别使用8个多进程和8个多线程去执行亿次运算时,耗时差距更大,输出如下:
本机为 64 核 CPU 计算密集型任务,多进程耗时 6.811635971069336 本机为 64 核 CPU 计算密集型任务,多线程耗时 113.53767895698547
可见在64核的cpu机器下,同时使用8个多进程和4个多进程效率几乎一样。而使用多线程则就效率较慢。要最高效地利用CPU,计算密集型任务同时进行的数量应当等于CPU的核心数
示例2:400次,阻塞两秒,读取文件
使用多进程(4核cpu)
from multiprocessing import Process
import os, time
# I/0密集型任务
def work():
time.sleep(5) # 阻塞两秒
if __name__ == "__main__":
l = []
print("本机为", os.cpu_count(), "核 CPU")
start = time.time()
for i in range(1000):
p = Process(target=work) # 多进程
l.append(p)
p.start()
for p in l:
p.join()
stop = time.time()
print("I/0密集型任务,多进程耗时 %s" % (stop - start))
使用多线程(4核cpu)
from threading import Thread
import os, time
# I/0密集型任务
def work():
time.sleep(5) # 阻塞两秒
if __name__ == "__main__":
l = []
print("本机为", os.cpu_count(), "核 CPU")
start = time.time()
for i in range(1000):
p = Thread(target=work) # 多线程
l.append(p)
p.start()
for p in l:
p.join()
stop = time.time()
print("I/0密集型任务,多线程耗时 %s" % (stop - start))
输出:
本机为 64 核 CPU I/0密集型任务,多进程耗时 12.28218412399292 本机为 64 核 CPU I/0密集型任务,多线程耗时 5.399136066436768
说明:python的多线程有于GIL锁的存在,无论是多少核的cpu机器,也只能使用单核,从输出结果来看,对于IO密集型任务使用多线程比较占优。
FAQ:执行多进程的io密集型任务时,报了一个错:
OSError: [Errno 24] Too many open files
原因:linux系统限制
ulimit -n
# 输出 1024
解决:(临时提高系统限制,重启后失效)
ulimit -n 10240
总结
到此这篇关于Python多进程与多线程使用场景的文章就介绍到这了,更多相关Python多进程与使用场景内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









