Sleep() vs time.sleep()

当我转到 asyncio页面时,第一个示例是 hello world 程序。当我在 python3.73上运行它时,我看不出与正常的 谁能告诉我它们之间的区别,并给出一个重要的例子?有什么不同

In [1]: import asyncio
...:
...: async def main():
...:     print('Hello ...')
...:     await asyncio.sleep(5)
...:     print('... World!')
...:
...: # Python 3.7+
...: asyncio.run(main())
Hello ...
... World!


In [2]:


In [2]: import time
...:
...: def main():
...:     print('Hello ...')
...:     time.sleep(5)
...:     print('... World!')
...:
...: # Python 3.7+
...: main()
Hello ...
... World!

我故意把时间从1增加到5,希望看到一些特别的东西,但我没有。

102072 次浏览

You aren't seeing anything special because there's nothing much asynchronous work in your code. However, the main difference is that time.sleep(5) is blocking, and asyncio.sleep(5) is non-blocking.

When time.sleep(5) is called, it will block the entire execution of the script and it will be put on hold, just frozen, doing nothing. But when you call await asyncio.sleep(5), it will ask the event loop to run something else while your await statement finishes its execution.

Here's an improved example.

import asyncio


async def hello():
print('Hello ...')
await asyncio.sleep(1)
print('... World!')


async def main():
await asyncio.gather(hello(), hello())


asyncio.run(main())

Will output:

~$ python3.7 async.py
Hello ...
Hello ...
... World!
... World!

You can see that await asyncio.sleep(1) is not blocking the execution of the script.

In contrast, replacing the line await asyncio.sleep(1) with time.sleep(1), the output will be

Hello ...
... World!
Hello ...
... World!

because time.sleep is blocking and the first call of hello() has to finish first before the second call of hello() starts running.

Hope it helps :)

With time.sleep(1) below, first, test1() is run every one second, then test2() is run every one second:

import asyncio
import time


async def test1():
for _ in range(0, 3):
print('Test1')
time.sleep(1) # Here
        

async def test2():
for _ in range(0, 3):
print('Test2')
time.sleep(1) # Here
    

async def main():
await asyncio.gather(test1(), test2()) # Here


asyncio.run(main())

So, 6 seconds are taken to run test1() and test2() in total:

Test1 # 1 second
Test1 # 2 seconds
Test1 # 3 seconds
Test2 # 4 seconds
Test2 # 5 seconds
Test2 # 6 seconds

With asyncio.sleep(1) below, test1() and test2() are run every one second alternately:

import asyncio


async def test1():
for _ in range(0, 3):
print('Test1')
await asyncio.sleep(1) # Here
        

async def test2():
for _ in range(0, 3):
print('Test2')
await asyncio.sleep(1) # Here
    

async def main():
await asyncio.gather(test1(), test2()) # Here


asyncio.run(main())

So, only 3 seconds are taken to run test1() and test2() in total:

Test1 # 1 second
Test2 # 1 second
Test1 # 2 seconds
Test2 # 2 seconds
Test1 # 3 seconds
Test2 # 3 seconds

And, with time.sleep(0) below, first, test1() is run at once, then test2() is run at once:

import asyncio
import time


async def test1():
for _ in range(0, 3):
print('Test1')
time.sleep(0) # Here
        

async def test2():
for _ in range(0, 3):
print('Test2')
time.sleep(0) # Here
    

async def main():
await asyncio.gather(test1(), test2()) # Here


asyncio.run(main())

So, 0 second is taken to run test1() and test2() in total:

Test1 # 0 second
Test1 # 0 second
Test1 # 0 second
Test2 # 0 second
Test2 # 0 second
Test2 # 0 second

And, with asyncio.sleep(0) below, test1() and test2() are run at once alternately:

import asyncio


async def test1():
for _ in range(0, 3):
print('Test1')
await asyncio.sleep(0) # Here
        

async def test2():
for _ in range(0, 3):
print('Test2')
await asyncio.sleep(0) # Here
    

async def main():
await asyncio.gather(test1(), test2()) # Here


asyncio.run(main())

So, only 0 second is taken to run test1() and test2() in total:

Test1 # 0 second
Test2 # 0 second
Test1 # 0 second
Test2 # 0 second
Test1 # 0 second
Test2 # 0 second

Lastly, without time.sleep() or asyncio.sleep() below, first, test1() is run at once, then test2() is run at once:

import asyncio


async def test1():
for _ in range(0, 3):
print('Test1')
        

async def test2():
for _ in range(0, 3):
print('Test2')
    

async def main():
await asyncio.gather(test1(), test2()) # Here


asyncio.run(main())

So, 0 second is taken to run test1() and test2() in total:

Test1 # 0 second
Test1 # 0 second
Test1 # 0 second
Test2 # 0 second
Test2 # 0 second
Test2 # 0 second