Python 3.7-asyncio.sleep()和time.sleep()

an *_*use 3 python python-3.x python-asyncio python-3.7

当我转到asyncio页面时,第一个示例是hello world程序。当我在python上运行它时3.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!
Run Code Online (Sandbox Code Playgroud)

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

小智 12

下面的time.sleep(1)首先test1()每隔一秒运行一次,然后test2()每隔一秒运行一次:

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())
Run Code Online (Sandbox Code Playgroud)

因此,运行总共需要6 秒:test1()test2()

Test1 # 1 second
Test1 # 2 seconds
Test1 # 3 seconds
Test2 # 4 seconds
Test2 # 5 seconds
Test2 # 6 seconds
Run Code Online (Sandbox Code Playgroud)

使用下面的asyncio.sleep(1)test1()并且test2()每隔一秒交替运行一次:

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())
Run Code Online (Sandbox Code Playgroud)

因此,运行总共只需要3秒test1()test2()

Test1 # 1 second
Test2 # 1 second
Test1 # 2 seconds
Test2 # 2 seconds
Test1 # 3 seconds
Test2 # 3 seconds
Run Code Online (Sandbox Code Playgroud)

并且,在下面的time.sleep(0)中,首先test1()立即运行,然后test2()立即运行:

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())
Run Code Online (Sandbox Code Playgroud)

因此,运行时间为0 秒test1()test2()总共:

Test1 # 0 second
Test1 # 0 second
Test1 # 0 second
Test2 # 0 second
Test2 # 0 second
Test2 # 0 second
Run Code Online (Sandbox Code Playgroud)

并且,下面的asyncio.sleep(0)test1()test2()都同时交替运行:

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())
Run Code Online (Sandbox Code Playgroud)

因此,运行仅需​​ 0 秒test1()test2()总共:

Test1 # 0 second
Test2 # 0 second
Test1 # 0 second
Test2 # 0 second
Test1 # 0 second
Test2 # 0 second
Run Code Online (Sandbox Code Playgroud)

最后,如果没有下面的time.sleep()asyncio.sleep(),首先test1()是立即运行,然后test2()是立即运行:

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())
Run Code Online (Sandbox Code Playgroud)

因此,运行时间为0 秒test1()test2()总共:

Test1 # 0 second
Test1 # 0 second
Test1 # 0 second
Test2 # 0 second
Test2 # 0 second
Test2 # 0 second
Run Code Online (Sandbox Code Playgroud)


Nim*_*mal 8

您不会看到什么特别的东西,因为您的代码中没有太多异步工作。但是,主要区别在于它time.sleep(5)是阻塞的,并且asyncio.sleep(5)是非阻塞的。

time.sleep(5)被调用时,它会阻止脚本的整个执行,它会被搁置,只是冻结,无所事事。但是当您调用时await asyncio.sleep(5),它将在等待语句完成执行时要求事件循环运行其他内容。

这是一个改进的示例。

import asyncio

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

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

asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)

将输出:

~$ python3.7 async.py
Hello ...
Hello ...
... World!
... World!
Run Code Online (Sandbox Code Playgroud)

您可以看到这await asyncio.sleep(5)并没有阻止脚本的执行。

希望能帮助到你 :)

  • 更正:您写道“当调用 time.sleep(5) 时,它将阻止脚本的整个执行”。这仅适用于单线程脚本。但对于一般情况来说这是不正确的。time.sleep(5) 仅阻塞当前线程。 (12认同)
  • 这应该是官方的“hello world”示例。 (7认同)
  • 我的一些解释帮助我了解了同步与异步睡眠-如果您需要暂停执行整个脚本(假定可以同时工作),那就是睡眠。如果您需要暂停单个协程,则为asyncio.sleep (3认同)
  • @eyalzba 是的,这是有道理的。感谢您添加此评论:) (3认同)
  • 感谢 stackoverflow.com 和像您这样的程序员,标准 PY 文档中的许多“漏洞”都被覆盖了。(无法从 https://docs.python.org/3/library/asyncio.html 中挖掘出这一点!) (2认同)