【问题标题】:What is the effect of setting a linux socket - high priority?设置一个 linux 套接字有什么影响 - 高优先级?
【发布时间】:2016-10-26 04:31:08
【问题描述】:

来自linux套接字manpage

SO_PRIORITY
将所有数据包的协议定义优先级设置为 在这个套接字上发送。 Linux 使用此值对网络进行排序 queues:优先级较高的数据包可能会被优先处理 取决于所选的设备排队规则。

这是使用:

int optval=7 // valid values are in the range [1,7]  
             // 1- low priority, 7 - high priority  
setsockopt(socket, SOL_SOCKET, SO_PRIORITY, &optval, optlen)   

说,这个过程有:
一种。 10 个低优先级套接字(优先级=4),来自 socket_1 - socket_10
湾。 1 个高优先级套接字 (priority=7) - socket_11

以下场景会发生什么:

  1. send():进程在socket_1-socket_10socket_11 上发送多个消息,socket_11 上的 IMO 消息将优先于通过socket_1-@ 发送的消息987654332@。

  2. recv():如果上述所有套接字都收到多个消息,socket_11 在读取消息时是否比socket_1-socket_10 获得更高的优先级?

  3. 有没有办法使用lsofnetstat 等工具从命令行测量套接字优先级?

【问题讨论】:

  • 优先级仅与发送数据包有关。你引用的文件是这样说的。所以对recv() 的影响为零。

标签: linux sockets tcp network-programming


【解决方案1】:

每个 Linux 网络接口都有一个所谓的 qdisc(排队规则)附加到它上面。您的问题的答案取决于使用的 qdisc。一些排队规则,如pfifo and bfifo,没有优先级的概念。因此,如果使用它们,答案很简单——不会有优先级

但是,对于优先级 qdisc,例如 pfifo_fast(通常是 Linux 上的默认 qdisc),套接字优先级可能会产生影响。

这张图片描述了 pfifo_fast qdisc 中发生的事情:

我们看到数据包根据它们的优先级被放入队列中。当接口发送下一个数据包的时间到了(实际上是,但我们不要进入那个),它总是会选择发送具有最高优先级的数据包。这意味着如果有多个数据包在等待,优先级最高的将首先发送。请注意,这需要接口拥塞 - 如果接口不拥塞并且数据包从操作系统到达后立即发送,则没有排队,因此没有优先级。

其他 qdisc 具有不同的结构和策略。例如 SFQ qdisc:

考虑到这一点,让我们回到您的问题:

  1. 根据 qdisc,是的,来自socket_11 的数据包可能会在来自其他套接字的数据包之前发送。如果使用pfifo_fast,并且如果socket_11 发送足够的流量以使出站网络接口饱和,那么来自其他套接字的数据包甚至可能根本不发送。这在实践中不太可能发生,因为在使其他资源饱和之前通常很难使网络接口饱和,除非它是无线接口。

  2. 数据包从机器的网络接口到套接字的路径比网络本身快得多。而且,您还记得,要使优先级产生任何效果,就必须有拥塞。在典型情况下,到达您的网络接口的数据包已经通过了网络传输的瓶颈,因此不太可能发生拥塞。

    您当然可以使用ingress qdiscother mechanisms 来人为地制造瓶颈,并确定传入流量的优先级。但你为什么要?仅当您正在构建流量整形器或类似的网络设备时,这才有意义。另外,由于这个 qdiscs 是一种低级机制,发生在更高级别的套接字之下(甚至在桥接或路由之前),我怀疑套接字的优先级可能会对 in 产生任何影响。

  3. 我不知道,但我很乐意学习。 This kernel module 接近了,但它似乎无法显示优先级标志,只能显示常规套接字选项。

【讨论】:

  • 感谢您的详细回答..它有很大帮助..我如何检查我的 linux 发行版中使用的 qdisc?
  • tc qdisc show。但它将是pfifo_fast :)
  • mm.. tc 未安装在我的系统上。有没有其他检查方法?或者我可以放心地假设我的内核有pfifo_fast ?我的linux内核版本是3.10.19
  • 试试ip addr show。你应该看到类似eth0: <BLAH BLAH BLAH> mtu 1500 qdisc pfifo_fast
  • 可以通过安装iproute apt-get install iproute来安装tc
【解决方案2】:

回答你的问题:

  1. 默认是,说明如下
  2. 没有优先级仅适用于发送,解释也在下面
  3. 我不这么认为,因为即使通过 /proc 接口也看不到此选项

关于 1 的详细信息

关于优先级、网络队列和设备规则的一些话。所有这些都与服务质量有关,尤其是与差异化服务 (DiffServ)。

当数据包被发送时,它被放入网络设备处理的接口“队列”。默认情况下,队列不是真正的队列,而是三个具有强优先级的真正 fifo。如果fifo0 中有数据包而不是fifo1 中的数据包等待。套接字优先级通过以下映射映射到此 fifo:

  • 0(尽力而为)是fifo1
  • 1-3(填充,散装,...)是 fifo2
  • 4 是 fifo1
  • 5 是 fifo2
  • 6-7(交互,控制)是fifo0
  • 8-15是fifo1

所以优先级 1 将在优先级 0 之后调度。

为了改变默认行为,使用“交通控制”(tc)实用程序。使用它,您可以在网络接口上配置优先级队列。这就是所谓的“设备排队规则”。您可以定义特定网络设备如何提供优先级(Malt 的回答对此有很好的解释)。

关于2的详细信息

Socket 的状态为“ready for read”/“not ready for read”,这是布尔值。如果任何数据到达未就绪的套接字,它会将状态从“未就绪”更改为“就绪”,这可以通过 select/poll 等函数或从阻塞的 recv 调用返回来看到。哪个线程会被唤醒不是取决于套接字优先级,而是取决于线程优先级。

所以如果你想优先考虑你需要的套接字

  • 要么将它们放在优先线程上
  • 或在选择/轮询后按代码优先级

【讨论】:

  • 感谢您的详细回复。对于#1,如果我的排队规则是 pfifo_fast,那么答案是肯定的?根据@Malt 的回答
  • @brokenfoot 我查看了 linux 内核源代码。 SO_PRIORITY 涉及套接字优先级字段,并在复制到从该套接字传出的所有数据包(skb->priority)之后。 skb->priority 真正用于选择fifo。但是有奇怪的映射:优先级 0 映射到 fifo1,1-3 到 fifo2,4 到 fifo1,5 到 fifo2,6 到 fifo0。
  • @brokenfoot 我已经更新了答案,同意我的新知识。
  • 能否请您提及有关socket-priority 映射到fifos 的源信息。谢谢!
  • @Dmitry:你确定吗?您的映射显示了从 4 个 TOS 位到队列/FIFO 的映射 - 这与从 SO_PRIORITY 到队列的映射不同吗?
猜你喜欢
  • 2014-10-27
  • 1970-01-01
  • 2011-11-24
  • 2015-11-08
  • 2017-02-17
  • 2012-02-11
  • 1970-01-01
  • 1970-01-01
  • 2010-12-12
相关资源
最近更新 更多