1

我正在构建一个向多个远程硬件发送和接收 UDP 数据包的系统。

  • 一个函数mySend将新信息传递给第三方 API,我必须使用该 API 来构造实际的 UDP 数据报。API 在其构建和发送数据报的工作期间锁定互斥锁。

  • 一个函数myRecv在工作线程中运行,反复要求第三方 API 轮询新数据。API 调用 UDP 接收函数,该函数运行selectrecvfrom从远程硬件获取任何响应。

由于我用来解码这些数据包的 API 的设计,侦听和处理传入数据包的线程目前存在问题,该 API 将自己的互斥锁锁定在对 UDP-receive 函数的调用周围。但是这个函数执行了一个阻塞 select


发送序列 接收序列


结果是互斥锁几乎总是被接收线程锁定,事实上,争用非常严重,mySend实际上永远无法获得锁。结果是基础线程被有效地死锁。

为了解决这个问题,我试图证明使监听套接字非阻塞并在没有数据可用的调用usleep之间执行。select

备选接收序列

现在,如果我的阻塞select有 3 秒超时,这与每 3 秒执行一次非阻塞select(在最坏的情况下)不同,因为在查找和处理传入数据包时引入了延迟。所以这个usleep周期必须要低很多,比如 300-500 毫秒。

我关心的主要是额外的系统调用——这是对 的更多调用select,以及对usleep. 有时,我预计在几十秒甚至几分钟内几乎没有传入数据,但也有可能在某些时间段内,我预计可能会在几秒钟内收到 40KB 的数据。

如果这都是我自己的软件,我的第一反应是加强互斥锁的使用,这样就没有任何锁定select,这样就不会有问题了。但是如果我不需要的话,我想避免在 3rd-party API 中进行黑客攻击。

在这个阶段,简单的基于时间的分析还不够,因为这种机制需要很好地扩展,而我现在没有办法进行大规模测试。因此,我试图收集一些轶事证据来指导我的决策。

  • 迁移到非阻塞套接字是正确的方法吗?
  • 还是我最好破解第三方 API(我宁愿不这样做)以加强他们的互斥锁使用?
4

1 回答 1

0

我、我的团队和 3 rd方库的开发人员都得出结论,该 hack 足够适合部署,并且超过了与我的潜在替代解决方法相关的问题和缺点。

当然,真正的解决方案是将适当的设计修复推送到第 3库中;这是一条路,因为它会相当广泛,没有人真正关心足够,但它确实为我们提供了这个问题的答案。

于 2013-11-27T21:25:20.703 回答