我在阻塞套接字上执行select()
而没有超时select(sock+1, &rfd, NULL, NULL, NULL)
。
这发生在一个目标是分派传入数据的线程中。另一个监视线程是管理对等体的保持活动,当它检测到死连接时,它将关闭套接字。
在这种情况下,我希望select()
以-1
返回。它在Windows上执行,但从不在Linux上运行,因此当对等体非优雅地消失时,调度线程将永远锁定。为了完整性,有待传输的待处理数据,我试图使用SO_LINGER
,但这并没有改变任何东西。
问题可以通过在select()
设置超时来解决,在关闭和超时之后的情况下,select()
最终会以-1
退出,但我想,在阅读文档时,没有超时的select()
仍会在关闭时退出,即使对等方没有响应。
我是否滥用select()
或是否有更好的方法来处理半开插座?
答案 0 :(得分:1)
是的,你滥用了select
。 man select
州:
如果select()监视的文件描述符在另一个线程中关闭,则结果未指定。在某些UNIX系统上,select()取消阻塞并返回,并指示文件描述符已准备就绪(后续I / O操作可能会因错误而失败,除非另一个文件描述符在返回的时间select()和执行了I / O操作)。在Linux(以及其他一些系统)上,关闭另一个线程中的文件描述符对select()没有影响。总之,任何依赖于此场景中特定行为的应用程序都必须被视为错误。
因此您无法关闭其他线程的连接。不幸的是poll
有同样的问题。
修改
有几种可能的解决方案,我没有足够的有关您的应用程序的信息。可以考虑改变以下内容:
epoll
代替select
。 select
是一个非常古老的功能,它是在线程未被认真考虑时及时设计的。