首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >异步睡眠:亚毫秒间隔睡眠

异步睡眠:亚毫秒间隔睡眠
EN

Stack Overflow用户
提问于 2019-02-02 20:23:33
回答 1查看 10.1K关注 0票数 7

我正在建造一个基于覆盆子的装置。它将有几个并行的功能,应该同时工作。在本例中,使用异步似乎是一个合理的选择(嗯,我可以用线程用C++编写所有这些东西,但是python代码看起来要紧凑得多)

其中一个功能是通过GPIO脉冲驱动步进电机。这些脉冲应该是5-10微秒长。有什么方法可以让异步睡眠每隔一毫秒入睡一次呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-03 19:52:46

有什么方法可以让异步睡眠每隔一毫秒入睡一次呢?

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

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

代码语言:javascript
运行
复制
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下运行,如下所示:

代码语言:javascript
运行
复制
$ strace -fo trc -T python3.7 sleep1.py
<wait a second or two, then press Ctrl-C to interrupt>

trc文件将包含相当精确的引擎盖下所发生的事情的时间。在Python启动序列之后,程序基本上在无限循环中执行以下操作:

代码语言:javascript
运行
复制
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的两个调用,以及对stat的调用。第一个epoll_wait实际上是相关的,它指定超时(以毫秒为单位),并睡眠大约需要的时间。如果我们将睡眠时间降低到亚毫秒(例如100 e-6),strace显示异步仍然请求来自epoll_wait的1ms超时,并得到同样多的超时。同样的情况也发生在超时时间减少到15人时。如果指定一个14 us或更小的超时,异步实际上会请求一个非超时轮询,而epoll_wait将在8 us中完成。然而,第二个epoll_wait也需要8个我们,所以你不能指望任何形式的微秒分辨率。

即使您使用线程和繁忙的循环,您也可能会遇到GIL的同步问题。这很可能是在低级语言(如C++或Rust )中完成的,即便如此,您还是需要小心操作系统调度程序。

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

https://stackoverflow.com/questions/54497181

复制
相关文章

相似问题

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