我正在尝试在 Linux 环境中编写一个简单的 Python 脚本来测试以太网交换机,该交换机必须处理包含小负载(12 字节)的高频 UDP 消息。
基本设计是我有一台笔记本电脑(带有 Ubuntu VirtualBox),使用连接到 100Mbps 交换机(Netgear FS105)的 socket.recvfrom() 运行 python 脚本。该交换机连接到发送包含两个字节的 UDP 数据包的台式 PC(带有另一个 Ubuntu VirtualBox)。这些字节只是一个计数器,它允许我查看数据包在传输后是否被重新排序或丢失。
传输代码如下所示:
self.sock = socket.socket(socket.AF_INET,
socket.SOCK_DGRAM) # UDP
period_s = 1 / 5000.0 # 5KHz
while True:
udp_count = chr ((i >> 8) & 0xFF) + chr( i & 0xFF )
start_time_s = time.time()
self.sock.sendto(udp_count, (self.UDP_BROADCAST_IP, self.UDP_PORT))
remaining_idle_time_s = period_s - start_time_s
time.sleep(remaining_idle_time_s)
i += 1
每隔几秒,remaining_idle_time_s 就会返回负值,因为 self.sock.sendto() 函数花费的时间超过 0.2ms。
使用 cProfile,我可以看到 self.sock.sendto() 调用平均需要 0.14 毫秒,但有时需要长达 3 毫秒!使用 getsockopt() 我可以看到套接字发送缓冲区足够大(212992)。
我该怎么做才能让 sock.sendto() 返回得更快。我猜测需要 3ms 的实例是由于 CPU 决定执行另一项任务。有没有办法阻止我的程序进行这种上下文切换?
最佳答案
您想在非实时操作系统中执行实时任务(Linux 不是实时操作系统)。
Realtime并不意味着快,而是在指定的时间限制内完成任务:即防止上下文切换是一种方法,因为你的任务时间变得可预测。
使用 C 语言或编写内核驱动程序可以使其速度更快,但不确定。有一些硬实时 Linux 实现,例如 RTLinux但如果你的主机不是实时的,在虚拟机中运行它就没有意义。
在 Linux 中无法做到这一点,我对此感到非常高兴,因为阻止上下文切换的可能性意味着每个应用程序都可以阻止操作系统执行其所谓的重要操作工作....
关于python - Python 中使用 socket.send() 的 UDP 调用非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29528498/