微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

与阻塞 select() 一起使用时,非阻塞套接字真的是非阻塞的吗?

如何解决与阻塞 select() 一起使用时,非阻塞套接字真的是非阻塞的吗?

这是一个相当理论化的问题。如果套接I/Oreadwrite)设置为 O_NONBLOCK,但是此套接字在 fd_set 中设置为 select(),其中 阻塞(等待文件描述符变为可读或可写的事件),那么该套接字无论如何阻塞(由于select())?

为什么我要将套接字设置为非阻塞,即使阻塞(认)版本一旦变为可读(或可写)(感谢 select()),也不会阻塞,因为 {{1 }} 表示它有数据要读取(或写入),因此套接字能够在不阻塞的情况下使用该数据执行其操作。那么为什么要在 select() 阻塞时设置套接字非阻塞呢?

具有 select() 套接字的示例,但是阻塞 non-block 结合使用:

select()

解决方法

这是一个相当理论化的问题。如果套接字 I/O(读或写)设置为 O_NONBLOCK,但是此套接字在 fd_set 中设置为 select() 阻塞(等待文件描述符变为可读或可写的事件),则该套接字正在阻塞无论如何(由于 select())?

select 正在阻塞。套接字仍然是非阻塞的。

为什么我要将套接字设置为非阻塞,即使阻塞(默认)版本一旦变为可读(或可写)(感谢 select()),也不会阻塞,因为 select() 已经说过了有数据要读取(或写入),因此套接字能够在不阻塞的情况下使用该数据执行操作。

不,不,不!这不是一个安全的假设。不能保证后续的 readwrite 不会阻塞。如果您需要将来保证以后的操作不会阻塞,则必须将套接字设置为非阻塞。

那么为什么在 select() 阻塞时还要设置套接字非阻塞呢?

因为您不希望套接字上的操作被阻塞。 select 函数不能保证未来的操作不会被阻塞,并且人们已经因为过去的假设而被烧毁。

例如,您在 UDP 套接字上执行 select 并表示接收不会阻塞。但是在您调用 recv 之前,管理员会启用之前禁用的 UDP 校验和。猜猜怎么着,如果唯一接收到的数据报上的校验和不正确,那么您的 recv 将被阻止。

除非您认为自己可以预见到类似事情可能发生的所有方式,并且您绝对不能,否则如果您不希望它阻塞,则必须将套接字设置为非阻塞。

,

select 忽略文件描述符上的非阻塞标志,因为关注它没有任何意义。

  • select 正在(可能)同时检查多个文件描述符,它们可能具有不同的非阻塞标志。应该注意哪些?
  • select 有自己的显式超时,用于确定调用是阻塞还是非阻塞,还是阻塞了有限的时间。

可以说,在文件描述符上设置非阻塞“状态”标志是一个糟糕的设计——最好在每次调用时指定是阻塞还是非阻塞。如果您使用 recvsend 而不是 readwrite,您实际上可以做到这一点。所有在文件描述符上设置“非阻塞”的真正作用是它进行的调用不指定阻塞或非阻塞、非阻塞。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?