我不会告诉你什么
asyncio
。
担保
但根据执行情况,可以看出
asyncio.sleep()
(基本上是
call_later()
)在指定的时间间隔内睡眠。
但至少要有一个与系统时钟的分辨率相等的不准确度
在执行中使用。
让我们来弄清楚。首先,
asyncio
使用单调的时钟,它们有不同的分辨率
在不同的平台上
(包括Python和操作系统的分辨率)。例如,对于
Windows
来说,这与
15ms
一样多。
In terms of 担保, pay attention to the comment to the function
BaseEventLoop.time
:
def time(self):
"""Return the time according to the event loop's clock.
This is a float expressed in seconds since an epoch, but the
epoch, precision, accuracy and drift are unspecified and may
differ per event loop.
return time.monotonic()
现在让我们来看看asyncio
的事件循环来源code负责启动预定的定时器。
# Handle 'later' callbacks that are ready.
end_time = self.time() + self._clock_resolution
while self._scheduled:
handle = self._scheduled[0]
if handle._when >= end_time:
break
handle = heapq.heappop(self._scheduled)
handle._scheduled = False
self._ready.append(handle)
第end_time = self.time() + self._clock_resolution
行显示,回调可提前发射比计划的要好,但在时钟分辨率内。尤里-塞利瓦诺夫对此明确表示here:
在我看来,目前我们窥视着未来的时间。 我们为什么不做
end_time = self.time() - self._clock_resolution
以保证超时总是被触发的之后的时间,而不是之前? 我不明白如果我们这样做,性能怎么会变差。
真的,我们来运行下一个程序(Windows 10上的Python 3.8)。
import asyncio
import time
async def main():
print("Timer resolution", time.get_clock_info('monotonic').resolution)
while True:
asyncio.create_task(asyncio.sleep(1))
t0 = time.monotonic()
await asyncio.sleep(0.1)
t1 = time.monotonic()
print(t1 - t0)
asyncio.run(main())
我们看到上述的行为。
Timer resolution 0.015625
0.09299999987706542
0.0940000000409782
0.0940000000409782
0.10900000017136335
但在正文的开头,我说至少是时钟分辨率,因为asyncio
在合作多任务的条件下起作用,如果有一个贪婪的coroutine(或许多不那么贪婪的coroutine),不会太频繁地把控制权交给事件循环,我们就会有以下情况。
import asyncio
import time
async def calc():
while True:
k = 0
for i in range(1*10**6):
k += i
await asyncio.sleep(0.1) # yield to event loop
async def main():
asyncio.create_task(calc()) # start greedy coroutine
print("Timer resolution", time.get_clock_info('monotonic').resolution)
while True:
asyncio.create_task(asyncio.sleep(1))
t0 = time.monotonic()
await asyncio.sleep(0.1)
t1 = time.monotonic()
print(t1 - t0)
asyncio.run(main())
毫不奇怪,情况正朝着增加延迟的方向变化。