ThreadPoolExecutor
前言
Python中,ThreadPoolExecutor对Thread做了进一步封装。在Thread基础之上,使得多线程开发更简单了。另一方面,由于还存在ProcessPoolExecutor类,多线程与多进程的开发接口得到了统一。
在整个过程中,需要理清ThreadPoolExecutor的成员方法和Future的成员方法。
ThreadPoolExecutor
一个简单的多线程
ThreadPoolExecutor在concurrent.futures模块下,一个简单的多线程代码如下:
import time
from concurrent.futures import ThreadPoolExecutor
def print_hello():
for i in range(10):
time.sleep(1)
print("h{} hello".format(i))
def print_world():
for i in range(10):
time.sleep(1)
print("w{} world".format(i))
if __name__ == "__main__":
executor = ThreadPoolExecutor(max_workers=2)
task1th = executor.submit(print_hello)
task2ed = executor.submit(print_world)
# 输出:
h0 hello
w0 world
h1 hello
w1 world
h2 hello
...
可以见到,打印结果中的“hello”和“world”是交叉出现,这符合多线程行为。
submit
在上面的demo中,ThreadPoolExecutor(max_workers=2)
表示创建一个线程池,而它的管理人就是这里的实例对象executor,executor有一个submit()
方法,用来提交子线程需要执行的任务——在这里分别是函数print_hello()和函数print_world(),每个任务对应一个线程。跟**threading.Thread()**不同,你不需要用什么命令让它“动”起来(threading.Thread()中需要start()
),当你submit之后,子线程就去执行了。
下面是submit()
方法的源码:
# submit源码
class ThreadPoolExecutor(_base.Executor):
...
def submit(self, fn, *args, **kwargs):
with self._shutdown_lock:
...
f = _base.Future()
...
self._adjust_thread_count() # 在submit中执行了_adjust_thread_count()
return f # 返回Future的对象
def _adjust_thread_count(self):
num_threads = len(self._threads)
if num_threads < self._max_workers:</