通过一个例子来说明select的用法
1:一个非常简单的用法
int main ()
{
}
这里将键盘作为一个文件描述符,用select来它监视键盘文件描述符的变化情况
上述的select只监视文件描述符的读的变化情况,这里用一个fd_set readfd;来装要监视的文件描述符。
setFD_ZERO(&readfd); 将文件描述符readfd集合的所有位设置为0
(readset writeset 都是我们指定让内核测试的读写描述字集合)
FD_ISSET(keyboard,&readfd) 判断键盘描述符是否已经准备好读,即已经键入一个字符
这时候就可以将输入的字符打印出来。
===========================================================================
下面来说一下select的缺点吧。首先他可以监听的描述符的大小受到FD_SETSIZE大小的限制一般是1024
然后:如果有很多描述符已经准备就绪。我们需要遍历扫描描述符集合,来用FD_ISSET判断某个描述符是否可读或者可写或者异常。这样的如果set增大,那么耗时也将成线性增长。
============================================================================
下面来说一下poll吧:
一下是一段有bug的代码这里仅仅是为了做展示不要深究细节:
fds:是一个struct pollfd结构类型的数组,用于存放需要检测其状态的Socket描述符;每当调用这个函数之后,系统不会清空这个数组,操作起来比较方便;特别是对于socket连接比较多的情况下,在一定程度上可以提高处理的效率;这一点与select()函数不同,调用select()函数之后,select()函数会清空它所检测的socket描述符集合,导致每次调用select()之前都必须把socket描述符重新加入到待检测的集合中;因此,select()函数适合于只检测一个socket描述符的情况,而poll()函数适合于大量socket描述符的情况
看上述两段代码即可看出其区别。
poll() 函数不会受到socket描述符上的O_NDELAY标记和O_NONBLOCK标记的影响和制约,也就是说,不管socket是阻塞的还是非阻塞的,poll()函数都不会收到影响;而select则相反,如果socket是阻塞的socket 那么select的使用与不使用select的效果是一样的
所以poll() 函数的功能和返回值的含义与 select() 函数的功能和返回值的含义是完全一样,但是二者的内部实现是不一样的
strust pollfd结构说明:
typedef struct pollfd {
} pollfd_t;
if((fds[nIndex].revents & POLLIN) == POLLIN){//接收数据/调用accept()接收连接请求}
poll的可移植性不如select好。