SELECT对linux中read()的影响

effect of SELECT on read() in linux

本文关键字:影响 read linux SELECT      更新时间:2023-10-16

我有一个遗留代码正在执行此操作:

select(nFD + 1, &tReadFds, NULL, NULL, &timer);
.............
if (FD_ISSET(nFD, &tReadFds)) 
        n = read(nFD,len,x);

是读取将读取整个接收缓冲区(nFD),假设"len"answers"x"足够大。

我认为这里的SELECT只是一种阻塞方式,直到recv缓冲区中的数据可用。

简而言之,select是一个可以在不阻塞的情况下调用的函数(即它立即返回),返回后它会告诉您一个文件描述符列表,您可以在该列表上调用read(或write)而不阻塞。

如果你想在只用一个线程处理I/O的同时提供持久服务,那么这样的函数是至关重要的:在等待I/O的时候,你不能什么都不做,所以你需要一个确定性的方法来确保你可以进行非阻塞I/O。

编辑下面是一个典型的单线程select服务器的示例,使用伪代码:

while (true)
{
     select(...);
     read_available_data();
     process_data_and_do_work();  // expensive
}

这样的服务器从不需要空闲,而且昂贵的处理功能几乎会占用所有可用的计算时间(它只需要确保在需要更多数据时返回)。我认为select甚至允许上下文切换,所以这在多进程环境中会很好。

代码片段使用非NULL超时参数调用select()。代码等待套接字变得可读的时间最长。如果超时已过,则套接字不可读,FD_ISSET()将返回false,跳过read()调用。但是,如果套接字在超时之前变得可读,则FD_ISSET()将返回true,并且对read()的调用保证不会阻塞调用线程。它将立即返回,或者返回套接字的接收缓冲区中当前的任何数据(最大可达len字节),或者如果远程方已正常断开连接,则返回0。