TCP套接字:当select()表示有可用数据时,read()仍然可以使用EINTR失败吗?

pyn*_*exj 2 c sockets kernel network-programming tcp

select()用于read()TCP套接字的非阻塞.当select()表示有用于读取数据我不知道我是否还需要处理EINTRread().

Dav*_*rtz 6

是的,一点没错.该select功能是一种状态报告功能,可以在您调用select和注意到其返回值之间的某个时间报告某事物的状态.它绝对没有任何未来的保证,期限.

这是一种非常常见的误解.但是,考虑select确保将来的操作将提供某些特定结果,就像误认为检查磁盘上有空闲空间意味着将来的写入不会失败.即使您认为有足够的可用空间,也可以允许实现在没有足够空闲空间的情况下进行写入失败.并且空间可以填充以寻找空间并尝试使用它.

同样如此select.没有规则,实现必须以某种方式记住它给你一个打击select并且影响后续读取的实现.人们多次做出这种假设,并被它咬得可怕.不要以为只是因为你无法想到它会失败的方式,这意味着它不会失败.

例如,没有规则禁止实现执行以下操作:

  1. 收到数据包.
  2. 它是有效的TCP数据,因此select返回就绪.此时read发出的A 将返回数据.
  3. 在实现可以确认数据之前,网络接口的写入队列已满.
  4. 由于实现看到由于完整队列而无法立即发送ACK,因此它只是选择丢弃该数据包并强制另一端重新发送
  5. read由于没有要读取的数据,后续操作会阻塞.

如果您认为某些标准禁止它,请引用标准.一个read一个后select命中失败有任何理由read之前,select击中可能会失败.该select功能永远不会提供未来保证.