Select()在编程中的使用

本文介绍了网络编程中的select函数,详细分析了select的使用理由、函数原型、参数及返回值。通过理解fd_set结构体和timeval结构体,以及FD_SET等相关宏的作用,帮助读者更好地掌握select在处理非阻塞读写中的应用。
摘要由CSDN通过智能技术生成

  最近接触到了网络编程,感觉select这个函数还是蛮实用的,也可以让代码显得高端。下面就先来总结下从各位大神汲取的知识,再次消化下。

使用select()理由

  可以使程序进行非阻塞的读写,从而能大大提高程序的执行效率。
  比如在原本应该recv阻塞之前,先加个select来判断是否有数据到来,如果有再进行接收,如果没有则直接跳过。

select函数原型及参数分析

select原型

  int select(int maxfdp,
  fd_set *readfds,
  fd_set *writefds,
  fd_set *errorfds,
  struct timeval*timeout);

select参数分析

  首先同前辈们一样先分析一下select参数中的fd_set和timeval结构体,进而更快理解select中各参数的作用。

fd_set(结构体)

  fd_set是一个文件描述符集合,也可以是一个句柄的集合。
  套用一个经常听的概念,即Unix下一切皆文件,就可以知道select的作用会很大,管道,设备,FIFO等都是文件,当然Socket也是文件,而且一般select与Socket搭配会用的更多。
  而对于fd_set的赋值,我们可以通过宏来进行该结构体的相应操作,如:
  FD_SET( int, fd_set* ): 将一个给定的文件描述符加入集合;
  FD_ZERO( fd_set* ):清空集合,这里需要注意,对文件描述符集合进行设置之前都必须对该文件描述符进行FD_ZERO的操作,即初始化的操作。如果不清空,会导致结果不可知;(具体原因稍后讲到)
  FD_CLR( int, fd_set* ):将一个给定的文件描述符从集合中删除;
  FD_ISSET( int, fd_set* ):检查集合中的文件描述符是否可读写。

timeval(结构体)

  其代表一个时间值。有秒数与毫秒数两个变量,结构体如下:
struct timeval {
time_t tv_sec; /* 秒数 */
suseconds_t tv_usec; /* 毫秒数 */
};

FD_SET等相关宏的阐述

  既然fd_set是结构体,那到底是由哪些变量组成的呢,为什么每次设置赋值前需要清空呢,这些宏到底对fd_set干了什么,又是怎么干的呢?下面将对这些问题进行分析解决。

  首先我们先在程序中通过sizeof()打印出fd_set的大小为128字节,怎么会是128字节,先放着后续说。
  其次了解到fd_set中是每一位表示一个文件描述符。
  最后一个字节8位。
  所以综上所述,fd_set一般最大能保存128(字节) * 8个文件描述符,也就是1024个文件描述符。这个值在Unix中通常会用头文件”sys/select.h”中的FD_SETSIZE来定义,即FD_SETSIZE的值为1024。

  下面引用自一篇博客的说明进行上面宏的问题进行解答,博客地址如下:http://blog.sina.com.cn/s/blog_a43aa27401015kt9.html

为说明方便,取fd_set中的一个1字节进行说明,上面说到fd_set中的每一bit可以对应一个文件描述符fd。那么1字节长的fd_set最大可以对应8个fd。
(1)执行fd_set set; FD_ZERO(&set);则set用位表示是0000,0000。
(2)若fd=5,执行FD_SET(fd,&set);后set变为0001,0000(第5位置为1)
(3)若再加入fd=2,fd=1,则set变为0001,0011
(4)执行select(6,&set,0,0,0)阻塞等待
(5)若fd=1,fd=2上都发生可读事件,则select返回,此时set变为0000,0011。注意:没有事件发生的fd=5被清空

  这里可以看出,在每次select之后,没有事件发生的那一位会被清0。同时描述符集合能放多少个,取决于sizeof(fd_set)的值,这也限制了集合的使用数量,那么有什么方法可以突破这个限制吗?可以,下面引用上面博客的一段话进行解释:

  (1)可监控的文件描述符个数取决与sizeof(fd_set)的值。 (2)可以有效突破select可监控的文件描述符上限。
  (3)将fd加入select监控集的同时,还要再使用一个数据结构array保存放到select监

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值