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来测试。
我们从该函数的最后一个参数timeout开始介绍,它告知内核等待所指定描述符中的任何一个就绪可花多长时间,其timeval结构用于指定这段时间的秒数和微妙数。
这三个参数有以下三种可能。
永远等下去:仅在有一个秒数符准备好I/O时才返回。为此,我们把该参数设置为空指针
等待一段固定时间:在有一个描述符准备好I/O时返回,但是不超过由该参数所指向的timeval结构中指定的秒数和微妙数。
根本不等待:检查描述符后立即返回,这称为轮询(polling)。为此,该参数必须指向一个timeval结构,而且其中的定时值(由该结构指定的秒数和微妙数)必须为0。
前两种情形的等待通常会被进程在等待期间捕获的信号中断,并从信号处理函数返回。
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。
前两种情形的等待通常会被进程在等待期间捕获的信号中断,并从信号处理函数返回。
相关文章推荐
- p2098 求sky数
- LeetCode(86) Partition List
- HDU 2571 命运(DP)
- jni 使用java 调用C代码
- wifi万能钥匙下载 v3.2.36 官方手机版
- mongodb个人研究
- hdoj 超级楼梯 【递归】
- 高效MacBook工作环境配置
- HDU 2063.过山车【二分图、二分匹配初接触】【8月3】
- Currency Exchange【POJ--1860】【SPFA】
- [BZOJ 2038][cogs 1775]小Z的袜子
- 【Qt OpenGL教程】10:加载3D世界,并在其中漫游
- HBase Region split 策略
- C++零碎知识点
- UNIX网络编程卷一:第四章 基本TCP套接字编程
- 字符串扩展 SDUT 1916
- HDU 1166 树状数组和线段树
- Oil Deposits HDU杭电1241
- ehcache缓存
- hdoj 1686 Oulipo【求一个字符串在另一个字符串中出现次数】