一尘不染

select()之后read()会阻塞吗?

linux

我正在通过TCP /
IP套接字读取数据流。流负载非常不均匀。有时每秒会有大量数据到达,有时一个小时没有数据到达。在长时间不活动的情况下(远程服务器没有数据,但连接仍然在线),我的程序应采取一些措施。

我正在使用select()实现超时。它告诉我是否已经准备好数据,但是我不知道在不引起read()阻塞的情况下我可以读取多少数据。阻止是无法接受的,因为它的持续时间可能远远超过我需要的超时时间。

为了提高效率,将流读入大缓冲区,并为该缓冲区提供read()调用。

如果要填充的缓冲区大于套接字中当前可用的数据量,read()将在select()之后阻塞吗?


阅读 613

收藏
2020-06-02

共1个答案

一尘不染

实际上,它不应该阻塞(这就是select()的目的!),但实际上,它 可能
例外。通常,read()最多应返回您指定的最大字节数,其中可能包括零字节(这实际上是一件有效的事情!),但是在先前报告准备就绪后,它绝不应阻塞。

不过,请参见Linux select手册页:

在Linux下,select()可能会将套接字文件描述符报告为“准备读取”,但是随后的读取会阻塞。例如,这可能在数据到达但检查时校验和错误并被丢弃时发生。在其他情况下,文件描述符可能会虚假地报告为就绪。因此,在不应阻塞的套接字上使用O_NONBLOCK可能更安全。

2020-06-02