一、submit / result 方法
- submit 函数用来提交线程需要执行的函数和参数,submit函数是立即返回的,从print(task1)输出结果在print(f'get page {times} success') 输出结果之前可以得出
- result 函数用来获取线程结果,该方法是阻塞的,从print(f'get page {times} success') 输出结果 在print(task2.result()) 之前输出 可以得出
import time
def get_html(times):
time.sleep(times)
print(f'get page {times} success')
return times
executor = ThreadPoolExecutor(max_workers=2)
task1 = executor.submit(get_html, 3)
task2 = executor.submit(get_html, 2)
print(task1)
print(task2.result())
输出结果
二、as_completed 方法
as_completed() 方法是一个生成器,在没有任务完成的时候,会阻塞,在有某个任务完成的时候继续执行for循环下面的语句,从结果可以看出: 先完成的任务先通知主线程
import time
def get_html(times):
time.sleep(times)
print(f'get page {times} success')
return times
executor = ThreadPoolExecutor(max_workers=2)
all_task = [executor.submit(get_html,url) for url in [3,2,4]]
for future in as_completed(all_task):
data = future.result()
print(f"in main: get page {data} s success")
输出结果:
三、 map 方法
使用map方法无需使用submit方法,在生产环境比较常用,输出顺序和 urls 列表的顺序相同,就算 2s 的任务先执行完成,也会先打印出3s的任务先完成,再打印2s的任务完成
from concurrent.futures import ThreadPoolExecutor
import time
def get_html(times):
time.sleep(times)
print(f'get page {times} success')
return times
executor = ThreadPoolExecutor(max_workers=2)
for data in executor.map(get_html,[3,2,4]):
print(f'get {data} page')
输出结果:
总结:
- ThreadPoolExecutor 让线程的使用更加方便,减小了线程创建/销毁的资源损耗,无需考虑线程间的复杂同步,方便主线程与子线程的交互。
- 线程池的抽象程度很高,多线程和多进程的编码接口一致