I/O的多路转接: select

1. 概念:

     I/O多路转接技术, 是先构造一张有关描述符的列表, 然后调用一个函数, 直到这些描述符中的一个已准备好进行I/O时, 该函数才返回. 在返回时, 它告诉进程哪些描述符已经准备好可以进行I/O.

    在Linux下poll, pselect, select这三个函数都可以执行I/O多路转接操作, 今天我们主要说select函数.

 

2. select函数:

#include  < sys / select.h >

int  select( int  maxfdp1, fd_set  * restrict readfds, fd_set  * restrict writefds, fd_set  * restrict exceptfds,
               
struct  timeval  * restrict tvptr);

正常则返回准备就绪的描述符数, 超时则返回0, 出错则返回
- 1 .

下面对参数进行说明:

  • maxfdp1: MAX File Description Plus 1. 最大描述符+1.
  • tvptr: 等待时间, 用一个timeval结构的值表示, 有3种情况:
    • tvptr == NULL: 永远等待. 可被信号中断.
    • tvptr->tv_sec == 0 && tvptr->tv_usec == 0: 完全不等待, 测试所有指定的描述符并立即返回. 非阻塞轮询.
    • tvptr->tv_sec != 0 &7 tvptr->tv_usec != 0: 等待指定的时间数. 时间超过立即返回0. 可被信号中断.
  • readfds, writefds, exceptfds: 指向描述符集的指针, 分别是可读, 可写, 异常的描述符. 每个描述符集存放在一个fd_set数据类型中.

 

fd_set可进行以下3种处理:

  • 分配一个这种类型的变量.
  • 将这种类型的一个变量赋值给同类型的另一个变量.
  • 其他处理.

关于其他处理, 由以下几个宏来实现:

#include  < sys / select.h >

/*  判断fd是否在描述符集fdset中  */
int  FD_ISSET( int  fd, fd_set  * fdset);

在则返回非0, 不在则返回0.

 

#include  < sys / select.h >

/*  将一指定位清楚  */
void  FD_CLR( int  fd, fd_set  * fdset);

/*  设置fd_set变量的一个指定位为fd  */
void  FD_SET( int  fd, fd_set  * fdset);

/*  将fdset的所有位设置为0  */
void  FD_ZERO(fd_set  * fdset);

 

3. 说明:

    前面我们所说的"准备好", 具体地说是指:

  • 若对读集(readfds)中的一个描述符的read操作将不会阻塞, 则此描述符是准备好的.
  • 若对写集(writefds)中的一个描述符的write操作将不会阻塞, 则此描述符是准备好的.
  • 若异常状态集(exceptfds)中的一个描述符有一个未决异常状态, 则此描述符是准备好的. 现在, 异常状态包括:
    • 在网络连接上到达的带外数据.
    • 在处于数据包模式的伪终端上发生了某些状态.

    描述符的阻塞是否并不影响select的阻塞. 也就是说, 这是两种阻塞层关系, 比如: 读一个非阻塞描述符, 并且以超时值5s调用select, 则select最多阻塞5s. 又比如: 指定一个tvptr = NULL 来调用select, 则该描述符数据准备好或捕捉到一个信号之前, select是一直阻塞的.

 

4. pselect:

    POSIX.1 定义了一个select的变体, 即: pselect, 对于这个函数不多介绍, 只说一下和select的两点区别:

  • 超时结构, select用timeval, pselect用const timespec. 这使得时间更精确, 并且不会被修改.
  • pselect可使用一可选择的信号屏蔽字sigmask. 在调用pselect时, 以原子操作的方式安装该信号屏蔽字, 在返回时恢复以前的信号屏蔽字.

 

5. 实例:

    编写中, 等待添加...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值