2

I am new to python and struggling to understand why my coroutine is not working.

In the current code, the only one job is running and another is always stays idle. Why?

class Worker:    
    def job1_sync(self):
        count = 0
        while True:
            print('JOB A:', count)
            count = count + 1

    def job2_sync(self):
        count = 0
        while True:
            print('JOB B:', count)
            count = count + 1

    async def job1(self):
        await self.job1_sync()

    async def job2(self):
        await self.job2_sync()

    worker = Worker()
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    loop.run_until_complete(asyncio.gather(worker.job1(), worker.job2()))

1 Answer 1

6

Asyncio does not do multi-tasking or multithreading. What it does is it schedules tasks within one thread, using a cooperative model.

That is, the event loop runs again when the current task awaits something that will "block", and only then it schedules another task. Under the hood, async functions are coroutines, and calls to await make the corouting yield to the event loop, which resumes it a later point, when awaited condition arises.

Here you never await anything, so job1 never relinquishes control, so the event loop never has a chance to distribute computing power to other tasks.

Now if your job was to actually relinquish control, say by triggering a delay, then your code would work:

async def job1_sync(self):      # note the async : only async functions can await
    count = 0
    while True:
        print('JOB A:', count)
        count = count + 1
        await asyncio.sleep(1)  # main even loop gets control

TLDR: asyncio is useful for what it says: doing stuff asynchronously, allowing other tasks to make progress while current task waits for something. Nothing runs in parallel.

Sign up to request clarification or add additional context in comments.

3 Comments

Make sense. I misunderstood entire concept. Thanks a lot!
The OP might be looking for is await loop.run_in_executor(None, self.job1_sync). async def job1_sync contradicts its own naming - presumably the whole point of job1_sync is that it invokes legacy or third-party sync code that might not be easy to change to async.
Well, perhaps. Although I think someone already knowing asyncio and going after the problem you describe would have asked the question in a different way, like, how to use threading/ipc and asyncio together. So my guess was the code was a full example from someone learning to use asyncio.

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.