您的位置:首页 > 其它

select函数分析

2015-08-03 19:54 281 查看
一、I/O复用概述
I/O复用典型使用在下列网络应用场合。 
-当客户处理多个描述符(通常是交互式输入和网络套接字)时,必须使用I/O复用;
-一个客户同时处理多个套接字是可能的,不过比较少见;
-如果一个TCP服务器既要处理监听套接字,又要处理已连接套接字,一般就要使用I/O复用;
-如果一个服务器既要处理TCP,又要处理UDP,一般就要使用I/O复用; 
-如果一个服务器要处理多个服务或者多个协议,一般就要使用I/O复用。
I/O复用并非只限于网络编程,许多重要的应用程序也需要使用这项技术。

二、select函数
该函数允许进程指示内核等待多个事件中的任何一个发生,并只在有一个或多个事件发生或经历一段指定的时间后才唤醒它。
作为一个例子,我们可以调用select,告知内核仅在下列情况下发生时才返回: 
-集合{1,4,5}中的任何描述符准备好读; 
-集合{2,7}中的任何描述符准备好写; 
-集合{1,4}中的任何描述符有异常条件待处理; 
-已经历了10.2秒。

也就是说,我们调用select告知内核对哪些描述符(就读、写或异常条件)感兴趣以及等待多长时间。我们感兴趣的描述符不局限于套接字,任何描述符都可以使用select来测试。
<span style="font-size:14px;"> 	</span><span style="font-size:12px;">/* According to POSIX.1-2001 */
#include <sys/select.h>
/* According to earlier standards*/
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
<span style="white-space: pre;">						</span><span style="font-family: 'microsoft yahei'; white-space: pre-wrap;">返回:若有就绪描述符则为其数目,若超时则为0,若出错则为-1</span>
void FD_CLR(int fd, fd_set *set);
int  FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);</span>

我们从该函数的最后一个参数timeout开始介绍,它告知内核等待所指定描述符中的任何一个就绪可花多长时间,其timeval结构用于指定这段时间的秒数和微妙数。
<span style="font-size:14px; white-space: pre;">	</span><span style="font-size:12px;">struct timeval {
long    tv_sec;         /* seconds */
long    tv_usec;        /* microseconds */
};</span>

这三个参数有以下三种可能。

永远等下去:仅在有一个秒数符准备好I/O时才返回。为此,我们把该参数设置为空指针
等待一段固定时间:在有一个描述符准备好I/O时返回,但是不超过由该参数所指向的timeval结构中指定的秒数和微妙数。
根本不等待:检查描述符后立即返回,这称为轮询(polling)。为此,该参数必须指向一个timeval结构,而且其中的定时值(由该结构指定的秒数和微妙数)必须为0。

前两种情形的等待通常会被进程在等待期间捕获的信号中断,并从信号处理函数返回。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: