Python并发复习4- concurrent.futures模块(线程池和进程池)
Python标准库为我们提供了threading(多线程模块)和multiprocessing(多进程模块)。从Python3.2开始,标准库为我们提供了concurrent.futures模块,它提供了 ThreadPoolExecutor 和 ProcessPoolExecutor 两个类,实现了对threading和multiprocessing的更高级的抽象,对编写线程池/进程池提供了直接的支持。
Executor是一个抽象类,它不能被直接使用。但是它提供的两个子类ThreadPoolExecutor和ProcessPoolExecutor却是非常有用,顾名思义两者分别被用来创建线程池和进程池的代码。
核心原理是:concurrent.futures会以子进程的形式,平行的运行多个python解释器,从而令python程序可以利用多核CPU来提升执行速度。由于子进程与主解释器相分离,所以他们的全局解释器锁也是相互独立的。每个子进程都能够完整的使用一个CPU内核,可以利用multiprocessing实现真正的并行计算。
最大公约数案例:
1 from concurrent.futures.process import ProcessPoolExecutor 2 from concurrent.futures.thread import ThreadPoolExecutor 3 4 import time 5 6 def program_timer(func): 7 def inner(*args, **kwargs): 8 start = time.time() 9 result = func(*args, **kwargs) 10 end = time.time() 11 print(f'{func.__name__}共耗时{end-start}') 12 return result 13 return inner 14 15 16 def gcd(pair): 17 a, b = pair 18 low = min(a, b) 19 for i in range(low, 0, -1): 20 if a % i == 0 and b % i == 0: 21 return i 22 23 numbers = [ 24 (1963309, 2265973), (1879675, 2493670), (2030677, 3814172), 25 (1551645, 2229620), (1988912, 4736670), (2198964, 7876293) 26 ] 27 28 @program_timer 29 def _main1(): # 普通执行 30 for i in numbers: 31 gcd(i) 32 33 @program_timer 34 def _main2(): # 多线程 35 pool = ThreadPoolExecutor(max_workers=2) 36 pool.map(gcd, numbers) 37 38 @program_timer 39 def _main3(): # 多进程 40 pool = ProcessPoolExecutor(max_workers=2) 41 pool.map(gcd, numbers) 42 43 if __name__ == '__main__': 44 _main1() 45 _main2() 46 _main3()
执行结果:
_main1共耗时0.7035946846008301 _main2共耗时0.030988216400146484 _main3共耗时0.42536211013793945