问题描述
我正在编写一个特定的应用程序,该应用程序必须根据来自 UDP 协议的数据在屏幕上呈现图像,并尽可能减少延迟。整体程序设计无关紧要,代码清洁度或可维护性也无关紧要。我需要 1 毫秒的延迟(用于处理数据报并调用翻转视频缓冲区的回调)或更低。
现在,我正在考虑以下方法:socket.socket().recvfrom()
、selectors.DefaultSelector().register()
、asyncore.dispatcher
、multiprocessing.Process
、concurrent.futures.ProcesspoolExecutor().submit()
、twisted.internet.protocol.ConnectedDatagramProtocol
虽然 socket.recvfrom()
是最简单的方法,但我相信它意味着下面的 while true
循环会阻塞并且不允许侦听数据报,如果它们在 {{ 1}} 方法被调用(即没有缓冲区),我的应用程序将以 1500 Hz 的频率接收数据报。recvfrom()
框架是否足够快?是基于 twisted
还是基于回调?
我个人的偏好是使用 ProcesspoolExecutor,虽然我认为必须调用回调会浪费几分之一毫秒,而过程单线程代码是最快的。
我还想避免函数调用开销,因此无法为我收到的每个数据报调用某种回调。
我应该选择哪个?
解决方法
这个问题并不是真的可以回答。
- 很可能,处理 UDP 数据报不会成为此应用程序中的限制因素。至少,您可能需要对这些数据进行身份验证或至少进行错误检查,这意味着您需要进行一些加密。
- 您需要在您关心的环境中实施和衡量。对于一个数据配置文件的一个版本的 linux 可能是正确的答案在稍微不同的平台上可能是完全错误的,该平台具有稍微不同的输入数据特征。您提到的所有方法在性能方面可能都不错,因此我将重点放在可以让您以合理的方式组织代码的方法,然后仅在不满足您的性能预算时才切换策略。
在这里回答您更具体的问题,Twisted 本身基于多路复用器(我们尽量避免 select
,它具有性能和可扩展性问题,但是是的,select
是它可以使用的一种机制)。