Unix领域套接字:使延迟恒定

3
问题概述:AF_UNIX稳定发送,接收时突发。
我有一个应用程序B,通过Unix域数据报套接字接收数据。有一个对等应用程序A向其发送数据。A和B都在持续运行(并且是SCHED_FIFO)。我的应用程序A还打印接收时间。
对等应用程序B可以以不同的时间间隔发送数据(仅以毫秒为单位变化)。理想情况下(我所期望的),数据包发送延迟应与接收延迟完全匹配。例如:
A sends in time            :  5ms     10ms      15ms     21ms   30ms   36ms
B should receive in time   :  5+x ms  10+x ms   15+x ms  21+x ms ... 

其中x是一个恒定的延迟。

但当我进行实验时,我观察到B中的情况是:

A sends in time            :  5ms     10ms      15ms     21ms   30ms   36ms
B received in time         :  5+w ms  10+x ms   15+y ms  21+z ms ... 

(w、x、y、z是不同的延迟时间)。因此,在给定发送时间时无法预测接收时间。

这是因为Unix域套接字中涉及了一些缓冲。请建议一些解决问题的方法,以便从发送时间预测接收时间。我需要1毫秒精度。

(我正在使用vanilla Linux 3.0内核)


注意:我有一个可调参数/proc/sys/net/unix/max_dgram_qlen,可以设置为1。但仍然存在问题。可能是调度延迟的原因。 - Lunar Mushrooms
我的接收和发送都是阻塞的。 - Lunar Mushrooms
1
我不确定为什么在Unix域套接字中会有影响,但您是否已禁用了Nagle算法:https://en.wikipedia.org/wiki/Nagle%27s_algorithm - dave
1
@dave。Nagle算法不适用于SOCK_DGRAM。它是针对TCP的。 - Lunar Mushrooms
大多数情况下,示例只是为了说明问题。实际情况中,数据是音频。在回放时,B从数据包接收中推导出时间。我不想提及这些,因为那会引起无关的讨论。 - Lunar Mushrooms
显示剩余3条评论
1个回答

1
由于您正在使用阻塞的recv(),当没有数据报可用时,您的程序将无法调度。这对您的用例来说很糟糕--您希望您的程序保持活跃。因此,将您的recv()设置为非阻塞,并通过简单的忙等待来处理EAGAIN。这将消耗一个核心的100%,但我认为您会发现它有助于实现您的目标。

似乎是其中一个候选想法。但我无法让我的CPU保持繁忙状态 :-( - Lunar Mushrooms
3
所以您希望获得高精度、低延迟,但不能让CPU保持繁忙状态?祝您好运。 :) - John Zwinck
谢谢John :-)。但是让我试一试。 - Lunar Mushrooms
1
我不明白上下文切换开销如何会导致超过一毫秒的抖动,除非他的系统正在进行交换或调度程序中的运行队列非常长。 - jxh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接