我有遗留代码,这样做:
select(nFD + 1, &tReadFds, NULL, NULL, &timer);
.............
if (FD_ISSET(nFD, &tReadFds))
n = read(nFD,len,x);
读取将读取整个接收缓冲区(nFD),假设'len'和'x'足够大。
我认为这里的SELECT只是一种阻塞方式,直到数据在recv缓冲区中可用。
答案 0 :(得分:0)
简而言之,select
是一个可以不受阻塞地调用的函数(即它立即返回),并且在返回时它将告诉您一个文件描述符列表,您可以在其上调用read
(或write
)没有阻止。
如果您想在仅使用单个线程处理I / O时提供持久性服务,这样的功能至关重要:在等待I / O时,您无法承担 nothing ,并且因此,您需要一种确定性方法来确保您可以执行非阻塞I / O.
编辑。以下是典型的单线程select
- 服务器的示例,采用伪代码:
while (true)
{
select(...);
read_available_data();
process_data_and_do_work(); // expensive
}
这样的服务器永远不必空闲,昂贵的处理功能几乎可以占用所有可用的计算时间(它只需要确保在需要更多数据时返回)。我认为select
甚至允许上下文切换,所以这在多进程环境中会很好。
答案 1 :(得分:0)
代码段使用非select()
超时参数调用NULL
。代码正在等待一段时间,以使套接字变得可读。如果超时,则套接字不可读,FD_ISSET()
将返回false
,跳过read()
调用。但是,如果套接字在超时之前变得可读,FD_ISSET()
将返回true,并且保证调用read()
不阻止调用线程。它将立即返回,或者返回当前在套接字的接收缓冲区中的任何数据(最多len
个字节),或者如果远程方正常断开连接则返回0。