先看一个 demo 程序:
from concurrent import futures
import time
import random
def returnNumber(number: int)->int:
print("start return number {}".format(number))
time.sleep(random.randint(10, 20)) # 随机睡眠10-20秒
print("end return number {}".format(number))
return number # 返回参数本身
if __name__ == '__main__':
with futures.ThreadPoolExecutor(5) as executor: # __exit__方法会调用executor.shutdown(wait=True),在所有线程都执行完毕前阻塞当前线程
res = executor.map(returnNumber, range(0, 10)) # 返回一个生成器,保存的是每个线程处理完返回的结果。其中range序列中0-4交给线程池并发调用,当其中一个线程完成后,将5交给线程池处理,以此类推。
print(res)
print("-----end-----")
print(list(res))
再看程序运行结果:
start return number 0
start return number 1
start return number 2
start return number 3
start return number 4
<generator object Executor.map.<locals>.result_iterator at 0x0000014C656E1B48> # 从开头到这里,是一次执行完毕打印的。因为ThreadPoolExecutor开启5个线程的线程池,5个线程同时并发执行函数,并打印res为一个生成器
end return number 3 # 随机睡眠结束过后,首个线程结束
start return number 5 # 上述线程结束后,从线程池剔除,开启下一个线程,始终保持ThreadPoolExecutor处于5个线程的状态处理任务
end return number 4
start return number 6
end return number 2
start return number 7
end return number 1
start return number 8
end return number 0
start return number 9
end return number 5
end return number 6
end return number 8
end return number 9
end return number 7
-----end----- # 只有当所有线程在上下文管理器中执行完时,当前线程才解除阻塞
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 打印res返回的线程函数处理的结果