实时操作系统(RTOS)上的Python

Gök*_*ver 17 python rtos qnx python-stackless

我计划在RTOS平台上实现一个小规模的数据采集系统.(在QNX或RT-Linux系统上.)

据我所知,这些作业是使用C/C++执行的,以充分利用系统.然而,我很想知道并且想要学习一些经验丰富的人的意见,然后我盲目地进入编码行动,是否可行且更明智地用Python编写所有内容(从低级仪器通过闪亮的图形用户界面连接).如果没有,将设计的时序关键部分与"C"混合,或者用C编写所有内容,甚至不用一行Python代码.

或者至少使用Python包装C代码以便更容易地访问系统.

你建议我以哪种方式工作?如果你指出一些类似的设计案例和进一步的阅读材料,我会很高兴的.

谢谢

注1:强调QNX的原因是我们已经有一个基于QNX 4.25的数据采集系统(M300)用于我们的大气测量实验.这是一个专有系统,我们无法访问它的内部.进一步研究QNX可能对我们有利,因为6.4有免费的学术许可选项,Python 2.5附带,以及最近的GCC版本.我从未测试过RT-Linux系统,不知道它在稳定性和效率方面与QNX有多大可比性,但我知道Python系统的所有成员和非Python工具(如Google Earth)的新系统可以在大多数情况下开箱即用.

Bob*_*obC 22

我已经构建了几个全Python软实时(RT)系统,主循环时间从1毫秒到1秒.我一路上学到了一些基本的策略和策略:

  1. 使用线程/多处理从主线程卸载非RT工作,其中线程之间的队列是可接受的,并且可以进行协作线程(没有抢先线程!).

  2. 避免使用GIL.这基本上不仅意味着避免线程,而且最大限度地避免系统调用,特别是在时间关键操作期间,除非它们是非阻塞的.

  3. 实际使用C模块.C(通常)的事情变得更快!但主要是如果你不必编写自己的:保留Python,除非真的没有其他选择.优化C模块性能是一种PITA,尤其是在跨Python-C接口的转换成为代码中最昂贵的部分时.

  4. 使用Python加速器来加速代码.我的第一个RT Python项目从Psyco中受益匪浅(是的,我已经这样做了一段时间).我今天使用Python 2.x的一个原因是PyPy:LLVM的事情总是变得更快!

  5. 当需要关键时机时,不要害怕忙碌等待.使用time.sleep()在所需时间'偷偷摸摸',然后在最后1-10毫秒内忙等待.我已经能够通过大约10微秒的自定时获得可重复的性能.确保您的Python任务以最大OS优先级运行.

  6. Numpy ROCKS!如果您正在进行"实时"分析或大量统计数据,那么与使用Numpy相比,没有办法更快地完成更多工作并且工作量更少(代码更少,错误更少).不是我所知道的任何其他语言,包括C/C++.如果您的大多数代码都包含Numpy调用,那么您将非常非常快.我等不及Numpy端口到PyPy完成了!

  7. 请注意Python如何以及何时进行垃圾回收.监控内存使用情况,并在需要时强制GC.务必在时间要求严格的操作期间明确禁用GC.我的所有RT Python系统都在不断运行,Python喜欢占用内存.仔细编码可以消除几乎所有动态内存分配,在这种情况下,您可以完全禁用GC!

  8. 尝试尽可能分批进行处理.不要以输入速率处理数据,而是尝试以输出速率处理数据,这通常要慢得多.批量处理还可以更方便地收集更高级别的统计信息.

  9. 我提到过使用PyPy吗?嗯,值得一提两次.

使用Python进行RT开发还有许多其他好处.例如,即使您非常确定您的目标语言不能是Python,它也可以为Python开发和调试原型带来巨大好处,然后将其用作最终系统的模板和测试工具.多年来,我一直使用Python来创建系统"硬件"的快速原型,并创建快速的测试GUI.这就是我的第一个RT Python系统的出现:原型(+ Psyco)足够快,即使测试GUI正在运行!

-BobC

编辑:忘了提到跨平台的好处:我的代码几乎无处不在运行a)没有重新编译(或编译器依赖,或需要交叉编译器),和b)几乎没有平台相关的代码(主要用于misc之类的东西)文件处理和串行I/O).我可以在Win7-x86上开发并部署在Linux-ARM(或任何其他POSIX操作系统上,所有这些操作系统最近都有Python).PyPy目前主要是x86,但ARM端口的发展速度令人难以置信.

  • 迟到的问题,但感谢这个详细的答案.对我来说,这是最有趣的部分:_Careful编码可以消除几乎所有动态内存分配,在这种情况下,您可以完全禁用GC_.你能举一些关于这个仔细编码的例子吗? (2认同)

Mar*_*off 15

我无法代表那里的每一个数据采集​​设置,但他们中的大多数都花费大部分"实时操作"来等待数据进入 - 至少是我所做过的那些.

然后,当数据进来,你需要立即记录事件或响应它,然后又回到了等待的游戏.这通常是数据采集系统中最重要的时间部分.出于这个原因,我通常会说在数据采集的I/O部分坚持使用C,但是没有任何特别令人信服的理由不在非时间关键部分使用Python.

如果你有相当宽松的要求 - 可能只需要毫秒精度 - 这会增加一些在Python中做所有事情的重量.就开发时间而言,如果您已经熟悉Python,那么如果您在Python中执行所有操作并且仅在出现瓶颈时重构,则可能会更快地获得完成的产品.使用Python完成大部分工作也可以更容易地彻底测试代码,并且作为一般经验法则,代码行数会减少,因此错误的空间也会减少.

如果您需要专门的多任务(而不是多线程),Stackless Python也可能是有益的.这就像多线程一样,但是线程(或无法使用Stackless语言中的tasklet)不是操作系统级别的线程,而是Python /应用程序级别,因此大大减少了在tasklet之间切换的开销.您可以将Stackless配置为多任务协同或抢先.最大的缺点是阻塞IO通常会阻止整个tasklet集.无论如何,考虑到QNX已经是一个实时系统,很难推测Stackless是否值得使用.

我的投票将采用尽可能多的Python作为可能的路线 - 我认为它是低成本和高利益.如果您确实需要在C中重写,那么您已经拥有了可用的代码.


hob*_*bbs 7

一般来说,在实时环境中使用高级语言的原因是不确定性 - 当你运行例程一次时可能需要100us; 下次你运行相同的例程时,它可能决定扩展一个哈希表,调用malloc,然后malloc要求内核提供更多的内存,这可以做任何事情,从立即返回到返回毫秒后返回到几秒后返回错误,其中没有一个从代码中立即显现(或可控制).而理论上如果你用C(甚至更低)写作,你可以证明你的关键路径将"永远"(禁止流星撞击)在X时间内运行.

  • 是的,你可以随意吃多少盐.我想也许我的论点应该是"如果所有这些东西听起来像你的胡说八道,那么你就不会实时地担心你在写什么语言". (3认同)