我正在构建一个向多个远程硬件发送和接收 UDP 数据包的系统。
一个函数
mySend
将新信息传递给第三方 API,我必须使用该 API 来构造实际的 UDP 数据报。API 在其构建和发送数据报的工作期间锁定互斥锁。一个函数
myRecv
在工作线程中运行,反复要求第三方 API 轮询新数据。API 调用 UDP 接收函数,该函数运行select
并recvfrom
从远程硬件获取任何响应。
由于我用来解码这些数据包的 API 的设计,侦听和处理传入数据包的线程目前存在问题,该 API 将自己的互斥锁锁定在对 UDP-receive 函数的调用周围。但是这个函数执行了一个阻塞 select
。
结果是互斥锁几乎总是被接收线程锁定,事实上,争用非常严重,mySend
实际上永远无法获得锁。结果是基础线程被有效地死锁。
为了解决这个问题,我试图证明使监听套接字非阻塞并在没有数据可用的调用usleep
之间执行。select
现在,如果我的阻塞select
有 3 秒超时,这与每 3 秒执行一次非阻塞select
(在最坏的情况下)不同,因为在查找和处理传入数据包时引入了延迟。所以这个usleep
周期必须要低很多,比如 300-500 毫秒。
我关心的主要是额外的系统调用——这是对 的更多调用select
,以及对usleep
. 有时,我预计在几十秒甚至几分钟内几乎没有传入数据,但也有可能在某些时间段内,我预计可能会在几秒钟内收到 40KB 的数据。
如果这都是我自己的软件,我的第一反应是加强互斥锁的使用,这样就没有任何锁定select
,这样就不会有问题了。但是如果我不需要的话,我想避免在 3rd-party API 中进行黑客攻击。
在这个阶段,简单的基于时间的分析还不够,因为这种机制需要很好地扩展,而我现在没有办法进行大规模测试。因此,我试图收集一些轶事证据来指导我的决策。
- 迁移到非阻塞套接字是正确的方法吗?
- 还是我最好破解第三方 API(我宁愿不这样做)以加强他们的互斥锁使用?