【问题标题】:Python async generator function without time drift没有时间漂移的 Python 异步生成器函数
【发布时间】:2021-09-15 11:40:55
【问题描述】:

我正在尝试模拟一系列数字的生成,如下面的代码所示。我想在没有时间漂移的情况下定期执行此操作,并且跟踪调用 serial_sequence() 的次数,即不使用变量 num。 如何做到这一点?

在示例代码中,delay2 始终为 0.1,但它应该稍微小一些,因为事件循环在调用 serial_sequence() 之间的其他地方很忙。因此经过的时间超过 2.0 秒。

import  asyncio
import time
rx_data = list()
EOT = 20

async def serial_sequence():
    '''async generator function that simulates incoming sequence of serial data'''
    num = 0
    tprev = time.time()

    while True:
        dt = time.time() - tprev
        delay2 = 0.1 - dt #Want to avoid time drift
        print('dt: {}'.format(dt))
        print('delay2: {}'.format(delay2))
        await asyncio.sleep(delay2) #simulated IO delay
        tprev = time.time()
        num += 1
        yield  num

async def read_serial1():
    gen = serial_sequence()
    while(True):
        data = await gen.__anext__()
        rx_data.append(data)
        print('read_serial1:', data)
        if data == EOT:
            break
    return rx_data

async def main():
    start = time.time()
    task1 = asyncio.create_task(read_serial1())
    await(task1)
    stop = time.time()
    print('Elapsed: {}'.format(stop-start))

if __name__ == '__main__':
    asyncio.run(main())

【问题讨论】:

    标签: python python-3.x asynchronous python-asyncio


    【解决方案1】:

    while 循环中的代码本身需要一些时间来计算。您的示例中的时间漂移​​会累积,因为您将 dt 基于上一个时间步长 tprev 的时间。

    您可以改为使用serial_sequence 的绝对开始时间作为参考点,如下所示:

    async def serial_sequence():
        '''async generator function that simulates incoming sequence of serial data'''
        num = 0
        starttime = time.time()
    
        while True:
            dt = (time.time() - starttime) % 0.1
            delay2 = 0.1 - dt #Want to avoid time drift
            print('dt: {}'.format(dt))
            print('delay2: {}'.format(delay2))
            await asyncio.sleep(delay2) #simulated IO delay
            tprev = time.time()
            num += 1
            yield num
    

    通过更改EOT比较累积。 IE。将 EOT 加倍会使您的解决方案的时间漂移​​加倍,而对于这个来说,它几乎是恒定的。

    我的回答主要基于this answer to a very similar question

    【讨论】:

      猜你喜欢
      • 2020-11-20
      • 1970-01-01
      • 2019-11-16
      • 2023-04-10
      • 2022-11-04
      • 2015-11-29
      • 2017-12-06
      • 2010-12-20
      • 1970-01-01
      相关资源
      最近更新 更多