user13848261
user13848261

Reputation:

Python Asyncio confusion between asyncio.sleep() and time.sleep()

From the documentation, if we want to implement a non-blocking delay we should implement await asyncio.sleep(delay) because time.sleep(delay) is blocking in nature. But from what I could understand, it is the await keyword that cedes control of the thread to do something else while the function f() following the keyword i.e. await f() finishes its calculations.

So if we need the await keyword in order for asyncio.sleep(delay) to be non-blocking, what is the difference with its counterpart time.sleep(delay) if both are not awaited for?

Also, can't we reach the same result by preceding both sleep functions with a await keyword?

Upvotes: -1

Views: 2379

Answers (2)

jupiterbjy
jupiterbjy

Reputation: 3503

From one answer of somewhat similar topic:

The function asyncio.sleep simply registers a future to be called in x seconds while time.sleep suspends the execution for x seconds.

So the execution of that coroutine called await asyncio.sleep() is suspended until event loop of asyncio revokes after timer-expired event.

However, time.sleep() literally blocks execution of current thread until designated time is passed, preventing chance to run either an event loop or other tasks while waiting - which makes concurrency possible despite being single threaded.

For what I understand that's difference of following:

  1. counting X seconds with stopwatch yourself
  2. let the clock ticking and periodically check if X seconds has passed

You, a thread probably can't do other thing while looking at stopwatch yourself, while you're free to do other jobs between periodic check on latter case.


Also, you can't use synchronous functions with await.

From PEP 492 that implements await and async:

await, similarly to yield from, suspends execution of read_data coroutine until db.fetch awaitable completes and returns the result data.

You can't suspend normal subroutine, python is imperative language.

Upvotes: 1

deceze
deceze

Reputation: 522135

Also, can't we reach the same result by preceding both sleep functions with a await keyword?

No, that's the thing. time.sleep() blocks. You call it, then nothing will happen for a while, then your program will resume when the function returns. You can await at that point all you want, there's nothing to await.

asyncio.sleep() returns immediately, and it returns an awaitable. When you await that awaitable, the event loop will transfer control to another async function (if there is one), and crucially it will be notified when the awaitable is done, and resume the awaiting function at that point.

To illustrate what an awaitable is:

foo = asyncio.sleep()
print('Still active')
await foo
print('After sleep')

An awaitable is an object that can be awaited. You aren't awaiting the function call, you're awaiting its return value. There's no such return value with time.sleep.

Upvotes: 0

Related Questions