- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试测试一个使用 UDP 数据包以预定速率进行通信的系统。我希望能够使用具有设定数据包速率的 Python 测试工具来测试该系统。采样率可能是 20 个数据包/秒或 4500 个数据包/秒等。
在一些简单的测试中,我确定我的 Windows 机器每秒可以通过本地主机传递超过 150,000 个 UDP 数据包,因此我可以将其视为实验的上限。
让我们从这个 shell 结构开始创建一个速率限制器。此代码的灵感主要来自 this thread 中的代码.
import time, timeit
class RateLimiter:
def __init__(self, rate_limit):
self.min_interval = 1.0 / float(rate_limit)
self.last_time_called = None
def execute(self, func, *args, **kwargs):
if self.last_time_called is not None:
# Sleep until we should wake up
while True:
now = timeit.default_timer()
elapsed = now - self.last_time_called
left_to_wait = self.min_interval - elapsed
if left_to_wait <= 0:
break
time.sleep(left_to_wait)
self.last_time_called = timeit.default_timer()
return func(*args, **kwargs)
您可以像这样使用这个辅助类:
self._limiter = RateLimiter(4500) # 4500 executions/sec
while True:
self._limiter.execute(do_stuff, param1, param2)
对 timeit.default_timer()
的调用是 Python 中的一个快捷方式,可为您的平台提供最高精度的计时器,在 Windows 和 Linux 上的精度约为 1e-6 秒,这我们需要。
在这种方法中,sleep()
可以在不消耗 CPU 周期的情况下为您争取时间,但它会损害延迟的准确性。 This comment显示 Windows 和 Linux 之间关于 sleep()
小于 10ms 的差异。总结该评论,Windows 的 sleep()
仅适用于 1ms 或更多的值(任何小于都被视为零)但通常 sleep 时间少于请求的 sleep 时间时间,而在 Linux 中 sleep()
更精确,但通常 sleep 时间比请求的时间略更多。
上面的代码在我的 Windows 机器上是准确的,但对于更快的速度来说效率低下。当我在测试中请求 4500 个数据包/秒的速率时,我得到的中值为 4466 个数据包/秒(0.75% 误差)。 但是,对于高于 1000Hz 的速率,对 sleep()
的调用需要零时间,因此 RateLimiter 会消耗 CPU 周期,直到超过等待时间。不幸的是,我们别无选择,因为我们不能在 Windows 中使用小于 1 毫秒的非零 sleep 时间。
在 Linux 中,对 sleep()
的调用花费的时间比请求的时间长,产生的中值为每秒 3470 个数据包(22.8% 的错误)。虽然 Linux 中的 sleep()
花费的时间比预期的要长,但请求更高的频率(如 6000Hz)会产生高于 4500 的真实频率,因此我们知道它能够达到目标频率。问题出在我们的 sleep()
值中,必须将其更正为低于我们预期的值。我使用以下(错误的)方法执行了另一个测试。
在这种方法中,我们从不 sleep 。我们消耗 CPU 周期直到时间过去,这导致 Python 100% 使用它运行的核心:
def execute(self, func, *args, **kwargs):
if self.last_time_called is not None:
# Sleep until we should wake up
while True:
now = timeit.default_timer()
elapsed = now - self.last_time_called
left_to_wait = self.min_interval - elapsed
if left_to_wait <= 0:
break
# (sleep removed from here)
self.last_time_called = timeit.default_timer()
return func(*args, **kwargs)
在 Linux 中,这会产生 4488 个数据包/秒的中位数速率(0.26% 错误),这与 Windows 相当,但同样占用 CPU,因此效率非常低。
这就是我的意思。 我们如何在 Linux 中使用 sleep()
来保持合理的 CPU 使用率,同时仍具有良好的计时精度?
我认为这必须涉及某种监控和补偿流程,但我不太确定如何着手实现这样的事情。是否有解决此类纠错问题的标准方法?
最佳答案
保证这一点的唯一方法是使用实时操作系统调度。否则,您将受到调度程序的摆布,并可能随时被抢占(例如,如果有一些高优先级/低 nice 进程正在占用您的 CPU 周期)。事实上,sleep()
只是一种请求抢占特定持续时间的便捷方式。您总是有可能睡得比您要求的时间长得多。这就是 Windows 甚至不尝试休眠 <1ms 的原因;一旦考虑到调度程序的不确定性,它就无法达到那种精度。开箱即用,Linux 也不是,但它可以配置(通过 sched_setscheduler(2)
)是实时的,所以如果你问它会尝试。
关于python - 我们如何在 Linux 中使用 sleep() 来保持合理的 CPU 使用率,同时仍然具有良好的计时精度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27113720/
我在 linux (Centos) 上使用 pthread 编程?我想让线程休眠一小段时间以等待某些事情。我正在尝试使用 sleep()、nanosleep() 或 usleep() 或其他可以做到这
此要求出现在我的 Android 应用程序中,但它通常适用于 Java。我的应用程序每隔几秒钟“做某事”。我已经按如下方式实现了这一点(只是相关的 fragment - 不是完整的代码): fragm
我正在使用 esp8266 构建 IR 到 WiFi 桥接器。基本上,我正在构建一个连接到红外 Remote 内的 esp8266 的红外接收器,以通过 wifi 将接收到的红外远程按键转发到服务器。
我想让 Toast 出现,然后让 sleep 运行。 如果我这样做,Toast 会在 sleep 后出现,但我希望反过来。有人有建议吗?这是我的代码 switch (checkedRadioButto
我在做一件简单的事情,打印一条错误消息,延迟执行 5 秒,然后调用另一个函数,这是代码 public void saveAndDisplay() throws InterruptedException
我的 Activity 上有一个按钮,当我单击它时,我希望按钮改变颜色,等待一段时间,然后再次改变颜色。 我尝试过以下两个版本的 sleep : 尝试1: public void buClick(Vi
我尝试过这个: for(int i =0; i1。创建ScheduledExecutorService public static ScheduledExecutorService createSch
我有一个 Winform,需要等待大约 3 - 4 小时。我无法关闭并以某种方式重新打开应用程序,因为它在等待时在后台做的事情很少。 为了实现等待 - 不给 UI 线程造成麻烦和其他原因 - 我有一个
我在网上看到了下面一段关于 Linux 线程的代码。但是当我运行它时,所有线程似乎都在 sleep ,而不仅仅是主线程。为什么?另外,如果没有 sleep(5),“线程创建成功”语句会运行 3 次而不
我有一个 php 脚本,我需要每 5 秒运行一次(运行,等待它完成,等待 5 秒,再次运行) 我有两种方法。要么在脚本中有一个带有 sleep 功能的无限循环,看起来像这样: while (1) {
我有一个图形用户界面,我想显示一些文本,然后稍等一下。 我的代码看起来像这样: //do something (add JTextArea, revalidate, repaint) try{
我想知道安卓手机的 sleep 模式和深度 sleep 模式有什么区别,手机进入休眠模式和深度 sleep 模式会有什么影响。 请提供详细的答案。 问候,皮克斯 最佳答案 深度 sleep 模式与休眠
我正在学习 C。在这个节目中我使用 sleep 功能来减慢倒计时。我的教科书没有指定我应该包含的库来使用 sleep 功能。所以我使用它时没有为它包含任何特殊的库并且它可以工作。但它在代码块中给了我这
我正在尝试模拟按键按下和按键 Action 。 例如:2638 毫秒。 SendMessage(hWnd, WM_KEYDOWN, keyCode, 0); Sleep(2638); SendMess
我在 while 循环中调用一个线程 hibernate 1 秒。当标志为真时,循环将运行(标志为真无限时间)。在循环线程内应该 hibernate 1 秒,唤醒并增加计数器,检查 IF 条件,在 F
有很多文件说“你应该避免使用带警报的 sleep ,因为许多系统使用警报来实现 sleep ”。实际上,我正在为这个问题而苦恼。 那么,当 sleep() 不能很好地处理警报时,是否有人可以帮助我“
我有两个带有图像的jlabel..我尝试在单击另一个标签时更改标签中的图像..(例如游戏)..我有一个问题..当我编写 Thread.sleep 时,图像没有改变..请参阅代码: public cla
我正在研究多线程,我有一个关于线程 sleep 方法的问题。当我在已经处于 sleep 线程(时间 t2)中执行 sleep()(时间 t1)方法时。总 sleep 时间为 t1+t2 或 t2(如果
如果我们不向 sleep( ) 函数传递任何参数,默认 sleep 时间是多少? #include int main() { int pid,dip,cpid; pid = fork(
当我转到 asyncio 页面时,第一个示例是一个 hello world 程序。当我在 python 3.73 上运行它时,我看不出与正常的有什么不同。 谁能告诉我区别并举一个重要的例子? In [
我是一名优秀的程序员,十分优秀!