asyncio:休眠亚毫秒

2024-06-16 10:25:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在建立一个基于树莓皮的设备。它将有几个并发函数,这些函数应该同时工作。在这种情况下,使用AsiCIO看起来是一个合理的选择(我可以用C++编写C++中的所有这些东西,但是Python代码看起来更紧凑)

其中一个功能是通过GPIO脉冲驱动步进电机。这些脉冲应为5-10微秒长。有没有一种方法可以在亚毫秒的时间间隔内使用异步睡眠来进入睡眠状态?在


Tags: 方法函数代码功能gpio间隔状态时间
1条回答
网友
1楼 · 发布于 2024-06-16 10:25:09

Is there a way to get asleep for a sub-milliseconds intervals with asyncio sleep?

在Linux上,asyncio使用epoll_wait系统调用,该调用以毫秒为单位指定超时,因此任何次毫秒都不起作用,尽管可以在asyncio.sleep()中指定它。在

您可以通过运行以下程序在计算机上进行测试:

import asyncio, os

SLEEP_DURATION = 5e-3  # 5 ms sleep

async def main():
    while True:
        # suspend execution
        await asyncio.sleep(SLEEP_DURATION)
        # execute a syscall visible in strace output
        os.stat('/tmp')

asyncio.run(main())

将程序保存为sleep1.py,并在strace下运行,如下所示:

^{pr2}$

trc文件将包含相当精确的幕后活动时间安排。在Python启动序列之后,程序基本上在无限循环中执行以下操作:

24015 getpid()                          = 24015 <0.000010>
24015 epoll_wait(3, [], 1, 5)           = 0 <0.005071>
24015 epoll_wait(3, [], 1, 0)           = 0 <0.000010>
24015 stat("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=45056, ...}) = 0 <0.000014>

我们看到对getpid()的调用,对epoll_wait的两次调用,最后是对{}的调用。第一个epoll_wait实际上是相关的,它以毫秒为单位指定超时,并在大约所需的时间段内休眠。如果我们将睡眠持续时间降低到亚毫秒,例如100e-6,strace表明asyncio仍然从epoll_wait请求一个1ms超时,并得到相同的超时值。同样的情况也发生在15秒的超时。如果指定14 us或更小的超时,asyncio实际上请求无超时轮询,epoll_wait在8us内完成。然而,第二个epoll_wait也需要8个us,所以你不能指望任何形状的微秒分辨率。在

即使您使用线程和繁忙的循环,您也可能会遇到GIL的同步问题。这可能是用C++或RISE等低级语言完成的,即使如此,你也需要对OS调度器小心谨慎。在

相关问题 更多 >