【发布时间】:2020-06-04 05:50:01
【问题描述】:
最近尝试使用asyncio异步执行多个阻塞操作。我用了函数loop.run_in_executor,好像该函数将任务放入线程池。据我所知线程池,它减少了开销创建和销毁线程,因为它可以在任务完成时放入一个新任务而不是销毁线程。我编写了以下代码以获得更深层次的理解。
def blocking_funa():
print('starta')
print('starta')
time.sleep(4)
print('enda')
def blocking_funb():
print('startb')
print('startb')
time.sleep(4)
print('endb')
loop = asyncio.get_event_loop()
tasks = [loop.run_in_executor(None, blocking_funa), loop.run_in_executor(None, blocking_funb)]
loop.run_until_complete(asyncio.wait(tasks))
和输出:
starta
startbstarta
startb
(wait for about 4s)
enda
endb
我们可以看到这两个任务几乎是同时进行的。现在我使用线程模块:
threads = [threading.Thread(target = blocking_ioa), threading.Thread(target = blocking_iob)]
for thread in threads:
thread.start()
thread.join()
和输出:
starta
starta
enda
startb
startb
endb
由于GIL的限制,只有一个线程在同时执行,所以我理解输出。但是线程池执行器是如何使这两个任务几乎同时执行的。线程池和线程有什么区别?以及为什么线程池看起来好像不受 GIL 限制?
【问题讨论】:
-
Python 经常在 GIL 上发布/获取。这意味着可运行的 GIL 控制线程都将获得很少的 sprint。它不是平行的,只是交错的。
标签: python multithreading threadpool