0

I was trying to run 2 tasks at the same time for a single client from the list but it doesn't work as expected - the tasks still ran synchronously (please see Output). Can you help me understand what's wrong with my code? Thank you.

Code

#!/usr/bin/env python3

import asyncio


async def do_b(client):
    print('{}: doing b...'.format(client))
    await asyncio.sleep(1)
    print('{}: b is done!'.format(client))


async def do_a(client):
    print('{}: doing a...'.format(client))
    await asyncio.sleep(1)
    print('{}: a is done!'.format(client))


async def loop_a():
    clients = ['CLIENT-1', 'CLIENT-2', 'CLIENT-3', 'CLIENT-4', 'CLIENT-5']

    for client in clients:
        task1 = asyncio.ensure_future(do_a(client))
        task2 = asyncio.ensure_future(do_b(client))

        await asyncio.gather(task1, task2)


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(loop_a())
    loop.close()

Output

CLIENT-1: doing a...
CLIENT-1: doing b...
CLIENT-1: a is done!
CLIENT-1: b is done!
CLIENT-2: doing a...
CLIENT-2: doing b...
CLIENT-2: a is done!
CLIENT-2: b is done!
CLIENT-3: doing a...
CLIENT-3: doing b...
CLIENT-3: a is done!
CLIENT-3: b is done!
CLIENT-4: doing a...
CLIENT-4: doing b...
CLIENT-4: a is done!
CLIENT-4: b is done!
CLIENT-5: doing a...
CLIENT-5: doing b...
CLIENT-5: a is done!
CLIENT-5: b is done!

EDIT:

Another question. How do I make it execute like this which does not follow their order in the list? Because currently, CLIENT-1 is being blocked by CLIENT-2, same as the other clients and I was trying to avoid that. Is this possible?

CLIENT-1: doing a...
CLIENT-2: doing a...
CLIENT-1: doing b...
CLIENT-3: doing a...
CLIENT-1: a is done!
CLIENT-1: b is done!
CLIENT-2: a is done!
CLIENT-3: a is done!
CLIENT-2: doing b...
CLIENT-2: b is done!
CLIENT-3: doing b...
CLIENT-3: b is done!
2
  • 1
    This doesn't directly answer your question but this site/book helped me understand asyncio. Maybe it will help you with your problem. pymotw.com/3/asyncio/control.html Commented May 31, 2018 at 23:20
  • a and b are running at the same time and the output shows that. clients 1,2,3,4,5 are running sequentially because you have an await asyncio.gather between them. Commented May 31, 2018 at 23:24

2 Answers 2

1

First, the two tasks aren't running synchronously, as you can see from the fact that doing b... keeps showing up in between doing a... and a is done!.

Each pair of tasks is finishing before the next client starts, but that's because you're explicitly asking for that to happen. If you don't want to await each pair, just… don't await each pair. For example:

futs = []
for client in clients:
    futs.append(asyncio.ensure_future(do_a(client)))
    futs.append(asyncio.ensure_future(do_b(client)))
await asyncio.gather(*futs)
Sign up to request clarification or add additional context in comments.

Comments

0

a and b are running at the same time and the output shows that. Clients 1, 2, 3, 4, and 5 are running sequentially because there is an await asyncio.gather between them.

You can merge all of the tasks into one list to make them run at the same time:

async def loop_a():
    clients = ['CLIENT-1', 'CLIENT-2', 'CLIENT-3', 'CLIENT-4', 'CLIENT-5']

    tasks = []
    for client in clients:
        tasks.append(asyncio.ensure_future(do_a(client)))
        tasks.append(asyncio.ensure_future(do_b(client)))
    await asyncio.gather(*tasks)

Now it prints:

CLIENT-1: doing a...
CLIENT-1: doing b...
CLIENT-2: doing a...
CLIENT-2: doing b...
CLIENT-3: doing a...
CLIENT-3: doing b...
CLIENT-4: doing a...
CLIENT-4: doing b...
CLIENT-5: doing a...
CLIENT-5: doing b...
CLIENT-1: a is done!
CLIENT-2: a is done!
CLIENT-3: b is done!
CLIENT-1: b is done!
CLIENT-3: a is done!
CLIENT-2: b is done!
CLIENT-4: a is done!
CLIENT-5: b is done!
CLIENT-4: b is done!
CLIENT-5: a is done!

1 Comment

I have another question. How do I make them execute without following the order in the list because currently CLIENT-1 is being blocked by CLIENT-2? @zvone

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.