作者:李春港
出处:https://www.cnblogs.com/lcgbk/p/14776820.html
最近遇到了一个很奇怪的问题,代码逻辑是这样:我使用Linux的socket进行TCP连接通信,客户端在一个独立的线程间隔5s时间不停给服务端发送心跳,服务端也会根据心跳回应。如果数据接收线程在8s内都没有接收到任何数据,则close(socket)关闭套接字。数据接收:在数据接收线程使用了select多路复用机制,对socket是否有数据到来进行监听。
当关闭套接字的时候,数据接收线程发现select函数一直返回有文件描述符有数据到来,但是实际读取socket套接字文件描述符的时候发现一直返回-1。
这个原因我们可以通过Linux的手册查看select的说明即可知道答案,在Linux终端使用 man select 查看,我发现一下这一段内容:
Multithreaded applications
If a file descriptor being monitored by select() is closed in another thread, the result is unspecified. On some UNIX systems, select() unblocks and returns, with an indication that the file descriptor is ready (a subsequent I/O operation will likely fail with an error, unless another the file descriptor reopened between the time select() returned and the I/O operations was performed). On Linux (and some other systems), closing the file descriptor in another thread has no effect on select(). In summary, any application that relies on a particular behavior in this scenario must be considered buggy.
译文:
多线程应用程序
如果select()监视的文件描述符在另一个线程中被关闭,则结果是未指定的。 在某些UNIX系统上,select()解除阻塞并返回,并指示文件描述符已经就绪(后续的I/O操作可能会失败并出现错误,除非在返回select()和执行I/O操作之间重新打开文件描述符)。 在Linux(和其他一些系统)上,在另一个线程中关闭文件描述符对select()没有影响。 总之,在这个场景中,任何依赖于特定行为的应用程序都必须被认为是有bug的。
由select的手册得知,这是select函数的一个bug,所以我们在使用select的时候需要注意。
思路:
【Linux】Linux select多路复用socket一直返回-1(select的bug)
原文:https://www.cnblogs.com/lcgbk/p/14776820.html