首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >asyncio.sleep怎么没有阻塞线程?

asyncio.sleep怎么没有阻塞线程?
EN

Stack Overflow用户
提问于 2020-06-21 02:13:20
回答 2查看 5.1K关注 0票数 7

我正在一遍又一遍地阅读卢西亚诺·拉马略的“流利的Python”,但我无法理解异步。睡眠在异步中的行为。

书中有一个部分说:

除非您想阻止主线程,否则永远不要在异步协同中使用time.sleep,因此冻结事件循环,可能也冻结整个应用程序。(...)它应该从asyncio.sleep(延迟)中屈服。

在另一部分:

Python标准库中的每个阻塞I/O函数都释放GIL (.)time.sleep()函数还释放GIL。

由于time.sleep()可以在其他线程上释放GIL代码,但会阻塞当前线程。由于异步是单线程的,我理解time.sleep阻塞异步循环。

但是,asyncio.sleep()如何不阻塞线程呢?是否可以不延迟事件循环并同时等待?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-06-21 02:57:08

函数asyncio.sleep只是time.sleep

您可以用这个小示例测试两者的行为,看看asyncio.sleep(1)是如何不给出它将“睡眠”的时间的,因为这并不是它真正做的事情:

代码语言:javascript
运行
复制
import asyncio 
import time
from datetime import datetime


async def sleep_demo():
    print("async sleep start 1s: ", datetime.now().time())
    await asyncio.sleep(1)
    print("async sleep end: ", datetime.now().time())
    

async def I_block_everyone():
    print("regular sleep start 3s: ", datetime.now().time())
    time.sleep(3)
    print("regular sleep end: ", datetime.now().time())
    
    
asyncio.gather(*[sleep_demo(), I_block_everyone()])

这些指纹:

代码语言:javascript
运行
复制
async sleep start 1s:        04:46:55
regular sleep start 3s:      04:46:55
regular sleep end:           04:46:58
async sleep end:             04:46:58 

阻塞调用time.sleep阻止事件循环调度恢复sleep_demo的未来。最后,它仅在大约3秒后才获得控制权(尽管我们明确请求1秒异步睡眠)。

现在关于“time.sleep()函数也释放了GIL”,这并不矛盾,因为它只允许执行另一个线程(但是当前线程将在x秒内保持挂起)。两者看起来有点相似,在一种情况下,释放GIL是为了为另一个线程腾出空间,在asyncio.sleep中,事件循环获得控制权以调度另一个任务。

票数 7
EN

Stack Overflow用户

发布于 2020-06-21 02:46:40

在幕后,asyncio有一个“事件循环”:它是一个在任务队列上循环的函数。添加新任务时,它将添加到队列中。当任务产生时,它被挂起,事件循环移到下一个任务。挂起的任务将被忽略,直到它们恢复为止。当任务完成时,它将从队列中移除。

例如,当您调用asyncio.run时,它会将新任务添加到队列中,然后进入事件循环,直到没有其他任务为止。

很少引用官方文件的话:

事件循环是每个异步应用程序的核心。事件循环运行异步任务和回调,执行网络IO操作,并运行子进程。

事件循环使用协作调度:事件循环一次运行一个任务。任务等待未来的完成时,事件循环运行其他任务、回调或执行IO操作。

调用asyncio.sleep时,它将挂起当前任务,从而允许运行其他任务。好吧,我基本上是在重述文档

睡眠()总是挂起当前任务,允许运行其他任务。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62493718

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档