场景:两个线程在同一个套接字上发送 UDP,线程 1 想要设置与线程 2 不同的 diffserv/QoS 类。我们之前通过将 sendto() 调用包装在互斥体中并执行相应 QoS 类的 setsockopt() 解决了这个问题在 sendto() 之前和之后(然后解锁互斥锁)。
使用此解决方案在极少数情况下(由于与信号的交互)我们遇到了死锁/挂起,我的问题是 - 如果我们在 sendmsg() 调用中将所需的 QoS 类作为辅助数据发送,我们是否可以完全删除互斥锁? 澄清一下,sendmsg() 是原子的,因此数据报将使用正确的 QoS 类发送,而不会有来自线程 1 和 2 的 sendmsg() 调用相互干扰的风险?
我在 SO 上发现了类似的问题,所以我知道一个套接字上一个 UDP 数据报的正常 sendmsg() 是“原子的”,但问题是整个调用,包括临时更改套接字的 QoS 位,是否是原子的,如用户空间线程?
Linux内核中的相关补丁是这样的:
commit aa6615814533c634190019ee3a5b10490026d545
Author: Francesco Fusco <ffusco@redhat.com>
Date: Tue Sep 24 15:43:09 2013 +0200
ipv4: processing ancillary IP_TOS or IP_TTL
If IP_TOS or IP_TTL are specified as ancillary data, then sendmsg() sends out
packets with the specified TTL or TOS overriding the socket values specified
with the traditional setsockopt().
The struct inet_cork stores the values of TOS, TTL and priority that are
passed through the struct ipcm_cookie. If there are user-specified TOS
(tos != -1) or TTL (ttl != 0) in the struct ipcm_cookie, these values are
used to override the per-socket values. In case of TOS also the priority
is changed accordingly.
Two helper functions get_rttos and get_rtconn_flags are defined to take
into account the presence of a user specified TOS value when computing
RT_TOS and RT_CONN_FLAGS.
Signed-off-by: Francesco Fusco <ffusco@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>