我在FDSET上运行了一个select,其中包括一些TCP连接和一个未绑定的UDP连接。在Windows中,当我从另一个线程关闭UDP连接的套接字时,它会指示select返回。但是,在Ubuntu中,情况并非如此,为什么?
答案 0 :(得分:2)
如果这取决于您是否尝试在 select
期间关闭fd ,或之前 select
(和{{1} }})。在这两种情况下,由于下面列出的原因,行为是未定义的。也许它在Windows下做了一件事,但你不能依赖它。
如果您试图在 FD_SET
期间(即在输入select
系统调用之后但在返回之前)关闭fd ,则行为未定义由于这里列出的原因:What does select(2) do if you close(2) a file descriptor in a separate thread?
如果您尝试在select()
(和select
)之前关闭fd ,那么您正尝试FD_SET
然后FD_SET
在现已关闭的FD上,即无效。该标准位于http://pubs.opengroup.org/onlinepubs/009695399/functions/select.html,这表示select()
宏可能甚至不会要求FD_SET
查看您的FD。
如果fd参数较小,则这些宏的行为是不确定的 0或大于或等于FD_SETSIZE,或者如果fd不是有效的 文件描述符,或者如果任何参数是带有side的表达式 的效果。
如果确实如此(并且只有确实如此),select()
应该返回select
:
在以下条件下,pselect()和select()将失败并且 将errno设置为:
[EBADF]一个或多个文件描述符集指定了一个文件 描述符不是有效的打开文件描述符。
但你无法知道会出现这种情况,因为EBADF
可能同样会忽略无效的文件描述符。
为了完整起见,如果您在FD_SET
之前执行FD_SET
,然后执行close
,则应该看到select
。