python - Python 中使用 socket.send() 的 UDP 调用非常慢

标签 python linux udp

我正在尝试在 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/

相关文章:

python - 使用 cx_freeze 的 .py 到 .exe 会导致错误

java - 使用 Jython 编译应用程序

linux - 如何使 iproute2 多个上行链路与伪装一起工作

ctime 给出不正确的输出

ios - 从 iOS 设备流式传输到 Wowza 服务器的最简单方法是什么?

python - PyTorch 线性层输入维度不匹配

python Telegram Bot "context.bot.send_message"

linux - 在 Windows 中访问 QNX 文件系统

mobile - 使用 TCP 的小数据包不是个好主意吗?使用 UDP 更好

networking - DTLS 消息的最小大小