Linux 半开套接字上的select()在关闭()时不返回?
我正在阻塞套接字上执行Linux 半开套接字上的select()在关闭()时不返回?,linux,sockets,select,Linux,Sockets,Select,我正在阻塞套接字上执行select(),没有超时select(sock+1,&rfd,NULL,NULL,NULL) 这发生在目标是分派传入数据的线程中。另一个监视线程正在管理与对等方的保持活动状态,当它检测到死连接时,它将关闭套接字 在这种情况下,我希望select()返回-1。它在Windows上这样做,但在Linux上永远不会这样做,因此当对等线程不正常地消失时,调度线程将永远被锁定。为了完整性,还有待传输的数据,我尝试使用SO_LINGER,但这并没有改变任何事情 这个问题可以通过在se
select()
,没有超时select(sock+1,&rfd,NULL,NULL,NULL)
这发生在目标是分派传入数据的线程中。另一个监视线程正在管理与对等方的保持活动状态,当它检测到死连接时,它将关闭套接字
在这种情况下,我希望select()
返回-1
。它在Windows上这样做,但在Linux上永远不会这样做,因此当对等线程不正常地消失时,调度线程将永远被锁定。为了完整性,还有待传输的数据,我尝试使用SO_LINGER
,但这并没有改变任何事情
这个问题可以通过在select()
中设置一个超时来解决,在关闭和超时之后,select()
最终会以-1
退出,但我想,阅读文档时,没有超时的select()
在关闭时仍然会退出,即使对等方没有响应
我是误用了
select()
还是有更好的方法来处理半开插槽?是的,您误用了select
。人工选择
说明:
如果select()监视的文件描述符在另一个线程中被关闭,则结果是未指定的。在某些UNIX系统上,select()取消阻止并返回,并指示文件描述符已准备就绪(后续I/O操作可能会失败并出错,除非在select()返回和执行I/O操作之间再次打开文件描述符)。在Linux(和其他一些系统)上,关闭另一个线程中的文件描述符对select()没有影响。总之,在此场景中依赖于特定行为的任何应用程序都必须被视为有缺陷
所以您不能关闭来自其他线程的连接。不幸的是,poll
也有同样的问题
编辑 有几种可能的解决方案,我没有关于您的应用程序的足够信息。可考虑以下变更:
- 如果您在linux上,请使用
而不是epoll
,如果您在其他操作系统上,请使用其他现代轮询机制<代码>选择是一个非常古老的功能,它是在没有认真考虑线程的情况下及时设计的select
- 在选择线程和保持活动线程之间建立通信通道。当keep-alive线程检测到一个死的对等线程时,不要关闭套接字本身,而是指示select线程这样做。通常,它可以通过本地套接字完成。本地套接字被添加到select描述符集,当keep-alive线程向其写入内容时,select线程将被唤醒并可以执行操作李>