小编jup*_*bjy的帖子

asyncio.sleep 如何不阻塞线程?

我一遍又一遍地阅读“Luciano Ramalho”的“Fluent Python”,但我无法理解 asyncio.sleep 在 asyncio 中的行为。

书中有一段说:

永远不要在 asyncio 协程中使用 time.sleep 除非你想阻塞主线程,从而冻结事件循环和整个应用程序。(...) 它应该从 asyncio.sleep(DELAY) 产生。

另一方面:

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

随着 time.sleep() 释放 GIL 代码,其他线程可以运行,但会阻塞当前线程。由于 asyncio 是单线程的,我知道 time.sleep 会阻塞 asyncio 循环。

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

python multithreading gil

5
推荐指数
2
解决办法
1765
查看次数

可等待的 iter() 替代品?

通常在 IO 操作中我们用来iter()读取哨兵值:

from sys import stdout

with open(r"Z:\github\StackOverFlow\temp.json", "r") as fp:
    for chunk in iter(lambda :fp.read(64), ""):
        stdout.write(chunk)
Run Code Online (Sandbox Code Playgroud)

iter()但是除了for waitable之外还有其他选择吗asyncio.Queue.get()

from sys import stdout

with open(r"Z:\github\StackOverFlow\temp.json", "r") as fp:
    for chunk in iter(lambda :fp.read(64), ""):
        stdout.write(chunk)
Run Code Online (Sandbox Code Playgroud)

当然,这不会起作用,因为它需要可调用,await不能在非异步函数内调用。

情况不允许queue.get_nowait(),因为队列大部分时间都是空的。


简单的修复方法是使用while循环:

for val in iter(lambda: await queue.get(), sentinel):
    queue.task_done()
    print(val)
Run Code Online (Sandbox Code Playgroud)

但我担心这是否会损害可读性和清晰度。

python python-asyncio

5
推荐指数
1
解决办法
783
查看次数

标签 统计

python ×2

gil ×1

multithreading ×1

python-asyncio ×1