Python并发 :ThreadPoolExecutor
concurrent.futures
是Python中执行异步编程的重要工具,它提供了以下两个类:
1.ThreadPoolExecutor
from concurrent.futures import ThreadPoolExecutor def test(num): print("Threads" num) # 新建ThreadPoolExecutor对象并指定最大的线程数量 with ThreadPoolExecutor(max_workers=3) as executor: # 提交多个任务到线程池中 executor.submit(test, 1) executor.submit(test, 2) executor.submit(test, 3)
2、ProcessPoolExecutor
from concurrent.futures import ProcessPoolExecutor def test(num): print("Processs" num) # 新建ProcessPoolExecutor对象并指定最大的进程数量 with ProcessPoolExecutor(max_workers=3) as executor: # 提交多个任务到进程池中 executor.submit(test, 1) executor.submit(test, 2) executor.submit(test, 3)
等待任务完成
1、ThreadPoolExecutor构造实例的时候,传入max_workers参数来设置线程池中最多能同时运行的线程数目。
2、使用submit函数来提交线程需要执行的任务(函数名和参数)到线程池中,并返回该任务的句柄,注意submit()不是阻塞的,而是立即返回。
3、通过submit函数返回的任务句柄,能够使用done()方法判断该任务是否结束。
4、使用cancel()方法可以取消提交的任务,如果任务已经在线程池中运行了,就取消不了。
5、使用result()方法可以获取任务的返回值。查看内部代码,发现这个方法是阻塞的。
在提交任务之后,我们通常需要等待它们完成,可以使用如下方法:
1、result()
用于获取 submit()
方法返回的 Future
对象的结果。该方法是同步的,Block主线程,直至得到结果或者抛异常。
from concurrent.futures import ThreadPoolExecutor def test(num): print("Tasks" num) # 新建ThreadPoolExecutor对象并指定最大的线程数量 with ThreadPoolExecutor(max_workers=3) as executor: # 提交多个任务到线程池中,并使用result方法等待任务完成 future_1 = executor.submit(test, 1) future_2 = executor.submit(test, 2) future_3 = executor.submit(test, 3) print(future_1.result())
Task 1 Task 2 Task 3 None
2、add_done_callback()
from concurrent.futures import ThreadPoolExecutor def callback(future): print("Task done? ", future.done()) print("Result: ", future.result()) # 新建ThreadPoolExecutor对象并指定最大的线程数量 with ThreadPoolExecutor(max_workers=3) as executor: # 提交多个任务到线程池中,并添加“完成时”回调函数 future_1 = executor.submit(pow, 2, 4) future_2 = executor.submit(pow, 3, 4) callback_future_1 = executor.submit(callback, future_1)
当使用 ThreadPoolExecutor 创建的线程池对象后,我们可以使用 submit
、map
、shutdown
等方法来操作线程池中的线程以及任务。
1、submit方法
ThreadPoolExecutor的submit
方法用于将任务提交到线程池中进行处理,该方法返回一个Future对象,代表将来会返回结果的值。submit方法的语法如下:
from concurrent.futures import ThreadPoolExecutor def multiply(x, y): return x * y with ThreadPoolExecutor(max_workers=3) as executor: future = executor.submit(multiply, 10, 5) print(future.result()) # 50
2、map方法
ThreadPoolExecutor的map
方法用于将函数应用于迭代器中的每个元素,该方法返回一个迭代器。map方法的语法如下:
from concurrent.futures import ThreadPoolExecutor def square(x): return x * x def cube(x): return x * x * x with ThreadPoolExecutor(max_workers=3) as executor: results = executor.map(square, [1, 2, 3, 4, 5]) for square_result in results: print(square_result) results = executor.map(cube, [1, 2, 3, 4, 5]) for cube_result in results: print(cube_result)
3、shutdown方法
ThreadPoolExecutor的shutdown
方法用于关闭线程池,该方法在所有线程执行完毕后才会关闭线程池。shutdown方法的语法如下:
from concurrent.futures import ThreadPoolExecutor import time def task(num): print("Task {} is running".format(num)) time.sleep(1) return "Task {} is complete".format(num) with ThreadPoolExecutor(max_workers=3) as executor: futures = [executor.submit(task, i) for i in range(1, 4)] executor.shutdown()