asyncio: sleep for sub-millisecond interval(异步:休眠亚毫秒间隔)
问题描述
我正在构建一个基于覆盆子PI的设备。它将有几个应该同时工作的并发功能。在这种情况下,使用Asyncio看起来是一个合理的选择(嗯,我可以用C++用线程编写所有这些东西,但是Python代码看起来要紧凑得多) 功能之一是通过GPIO脉冲驱动步进电机。这些脉冲应为5-10微秒长。有没有办法在异步睡眠的情况下在亚毫秒间隔内入睡?
推荐答案
有没有办法使用异步睡眠在亚毫秒间隔内入睡?
在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下运行,如下所示:
$ strace -fo trc -T python3.7 sleep1.py
<wait a second or two, then press Ctrl-C to interrupt>
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的调用,最后是对stat的调用。第一个epoll_wait实际上是相关的,它以毫秒为单位指定超时,并休眠大约所需的时间段。如果我们将睡眠持续时间降低到亚毫秒级,例如100e-6,strace显示Asyncio仍然向epoll_wait请求1ms超时,并获得同样多的超时。同样的情况也会发生在暂停到15秒的时候。如果您指定14 us或更小超时,则Asyncio实际上请求无超时轮询,epoll_wait在8 us内完成。但是,第二个epoll_wait也需要8微秒,所以您不能指望任何形式的微秒分辨率。
即使您使用线程和繁忙循环,也很可能会遇到GIL的同步问题。这很可能是在低级语言(如C++或Rust)中完成的,即使如此,您也需要小心操作系统调度程序。
这篇关于异步:休眠亚毫秒间隔的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:异步:休眠亚毫秒间隔
基础教程推荐
- PANDA VALUE_COUNTS包含GROUP BY之前的所有值 2022-01-01
- 无法导入 Pytorch [WinError 126] 找不到指定的模块 2022-01-01
- PermissionError: pip 从 8.1.1 升级到 8.1.2 2022-01-01
- 在Python中从Azure BLOB存储中读取文件 2022-01-01
- 使用大型矩阵时禁止 Pycharm 输出中的自动换行符 2022-01-01
- 修改列表中的数据帧不起作用 2022-01-01
- Plotly:如何设置绘图图形的样式,使其不显示缺失日期的间隙? 2022-01-01
- 求两个直方图的卷积 2022-01-01
- 在同一图形上绘制Bokeh的烛台和音量条 2022-01-01
- 包装空间模型 2022-01-01
