I'm trying to run 2 async functions test1()
and test2()
with loop.run_until_complete() at the same time in Python as shown below:
import asyncio
async def test1():
for _ in range(3):
print("Test1")
await asyncio.sleep(1)
async def test2():
for _ in range(3):
print("Test2")
await asyncio.sleep(1)
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(test1()) # Here
loop.run_until_complete(test2()) # Here
But as shown below, they don't run with loop.run_until_complete() at the same time:
Test1
Test1
Test1
Test2
Test2
Test2
I know that if I use loop.run_forever() with loop.create_task() as shown below:
import asyncio
async def test1(loop):
for _ in range(3):
print("Test1")
await asyncio.sleep(1)
loop.stop() # Extra code to stop "loop.run_forever()"
async def test2(loop):
for _ in range(3):
print("Test2")
await asyncio.sleep(1)
loop.stop() # Extra code to stop "loop.run_forever()"
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.create_task(test1(loop)) # Here
loop.create_task(test2(loop)) # Here
loop.run_forever() # Here
I can run them at the same time as shown below but loop.run_forever() runs forever so to stop loop.run_forever(), the extra code loop.stop() is needed which is troublesome. In addition, I know that asyncio.gather() can also run them at the same time but it needs await
which I don't want:
Test1
Test2
Test1
Test2
Test1
Test2
So, how can I run them with loop.run_until_complete() at the same time?
CodePudding user response:
If you wouldn't insist on the loop.run_until_complete
you can achieve what you want to get by using the asyncio.gather
functionality, just like so:
import asyncio
async def test1():
for _ in range(3):
print("Test1")
await asyncio.sleep(1)
async def test2():
for _ in range(3):
print("Test2")
await asyncio.sleep(1)
async def main():
tasks = [test1(), test2()]
new_items = await asyncio.gather(*tasks)
return new_items
if __name__ == '__main__':
results = asyncio.run(main())
and the results would be as you'd expect-
==> python3 stack_overflow.py
Test1
Test2
Test1
Test2
Test1
Test2
CodePudding user response:
You can run 2 async functions test1()
and test2()
at the same time by calling the intermediate async function call_tests()
with loop.run_until_complete() as shown below. You also need to use asyncio.get_running_loop() and loop.create_task() in call_tests()
and await
is needed for the last loop.create_task() to run them at the same time as shown below:
import asyncio
async def test1():
for _ in range(3):
print("Test1")
await asyncio.sleep(1)
async def test2():
for _ in range(3):
print("Test2")
await asyncio.sleep(1)
async def call_tests(): # Here
loop = asyncio.get_running_loop() # Here
loop.create_task(test1()) # Here
await loop.create_task(test2()) # "await" is needed
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(call_tests()) # Call "call_tests()"
Finally, you can run them at the same time as shown below:
Test1
Test2
Test1
Test2
Test1
Test2
Be careful, if using await
for the first and last loop.create_task() both as shown below:
# ...
async def call_tests():
loop = asyncio.get_running_loop()
await loop.create_task(test1()) # Here
await loop.create_task(test2()) # Here
# ...
You cannot run them at the same time as shown below:
Test1
Test1
Test1
Test2
Test2
Test2
And, if using await
for the first loop.create_task() as shown below:
# ...
async def call_tests():
loop = asyncio.get_running_loop()
await loop.create_task(test1()) # Here
loop.create_task(test2())
# ...
You cannot run them at the same time and the last loop.create_task()
is exited without completed as shown below:
Test1
Test1
Test1
Test2
And, if not using await
for the first and last loop.create_task() both as shown below:
# ...
async def call_tests():
loop = asyncio.get_running_loop()
loop.create_task(test1()) # No "await"
loop.create_task(test2()) # No "await"
# ...
You can run them at the same time but the first and last loop.create_task()
both are exited without completed as shown below:
Test1
Test2