Reputation: 18730
I'm having trouble understanding how the asyncio.create_task()
function introduced in Python 3.7 is supposed to work. If I do:
import asyncio
async def helloworld():
print("Hello world from a coroutine!")
asyncio.create_task(helloworld())
def main():
loop = asyncio.get_event_loop()
loop.run_until_complete(helloworld())
if __name__ == "__main__":
main()
I get:
Hello world from a coroutine!
Hello world from a coroutine!
As output (ie the coroutine is run twice). How is this not infinite recursion though? I'd expect to see what I see when I use the await
keyword:
import asyncio
async def helloworld():
print("Hello world from a coroutine!")
await helloworld()
def main():
loop = asyncio.get_event_loop()
loop.run_until_complete(helloworld())
if __name__ == "__main__":
main()
With this I get:
Hello world from a coroutine!
Hello world from a coroutine!
Hello world from a coroutine!
... many more lines...
Traceback (most recent call last):
File "test3.py", line 53, in <module>
main()
File "test3.py", line 48, in main
loop.run_until_complete(helloworld())
File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 568, in run_until_complete
return future.result()
File "test3.py", line 37, in helloworld
await helloworld()
File "test3.py", line 37, in helloworld
await helloworld()
File "test3.py", line 37, in helloworld
await helloworld()
[Previous line repeated 984 more times]
File "test3.py", line 36, in helloworld
print("Hello world from a coroutine!")
RecursionError: maximum recursion depth exceeded while calling a Python object
How is the create_task
only being scheduled once, and what is the use case for when you might use it (since it has to be run within a context where the event loop is already running)?
Upvotes: 24
Views: 11491
Reputation: 10401
You could treat asyncio.create_task
as a daemon thread in a multi-threaded world. The loop stops when the "main" coroutine stops. So the other daemon threads just quits anyway.
Upvotes: 9
Reputation: 20769
The task isn't scheduled once, but the loop only runs until helloworld
is complete. You see the message print twice because the loop lets the next task run. After that, the tasks stop running because the loop isn't running anymore.
If you change
loop.run_until_complete(helloworld())
to
loop.create_task(helloworld())
loop.run_forever()
you'll see Hello world from a coroutine!
print out repeatedly.
Upvotes: 13