Issue
It strikes me that the run_in_executor()
method of the asyncio
library belongs to a loop
object.
In particular, what would be the difference if I chose to run a second thread alongside an async event loop the "usual" way, by import threading
, t = threading.Thread(target=...)
, t.start()
?
Perhaps the answer is by using the asyncio
module there are low level optimizations which can be made at runtime if the loop knows about additional threads?
Solution
You can always start another thread manually, but then you are responsible for giving it work, e.g. using a queue. In Python 3 concurrent.futures
provide a convenient API for offloading tasks to a thread pool, which it calls executor. The submit
method takes a function, gives it to a thread in the pool to run it, and immediately returns a handle that will provide the result (or propagate the exception) when it is ready.
run_in_executor
is about bringing that convenience to asyncio. Normally you're not supposed to run blocking code inside asyncio - even something as simple as time.sleep()
is forbidden, because it blocks the whole event loop. run_in_executor
allows you to break that rule. For example:
async def sleep_test():
loop = asyncio.get_event_loop()
print('going to sleep')
await loop.run_in_executor(None, time.sleep, 5)
#time.sleep(5)
print('waking up')
async def parallel():
# run two sleep_tests in parallel and wait until both finish
await asyncio.gather(sleep_test(), sleep_test())
asyncio.run(parallel())
Running this code shows that both instances of the coroutine sleep in parallel. If we used time.sleep()
directly, they would sleep in series because the sleep would block the event loop.
This example is of course silly because there is asyncio.sleep()
that suspends a coroutine without spending a slot in a thread pool, but it shows the basic idea. Realistic use cases for run_in_executor
include:
- running CPU-bound code, such as numpy calculations, from within asyncio
- invoking legacy code that hasn't yet been ported to asyncio
- blocking calls where non-blocking APIs are simply unavailable (database drivers, file system access)
Answered By - user4815162342
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.