Chinaunix首页 | 论坛 | 博客
  • 博客访问: 567753
  • 博文数量: 50
  • 博客积分: 4764
  • 博客等级: 上校
  • 技术积分: 597
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-18 09:00
个人简介

资深IT码农,擅长Linux、C/C++、bash

文章分类

全部博文(50)

文章存档

2015年(17)

2014年(2)

2011年(7)

2010年(4)

2009年(20)

分类: C/C++

2015-07-23 17:15:29

select用法小结

select函数声明如下:

点击(此处)折叠或打开

  1. int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

timeout 的使用

select函数的最后一个参数 timeout(注意它的数据类型)用来指定超时值,有下面三种情况:
  1. 若传入NULL,就是将select置于阻塞状态,一定等到监视文件描述符集合(file descriptor set)中某个文件描述符发生变化为止;
  2. 若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件描述符无变化返回0,有变化返回一个正值;
  3. timeout的值大于0,这就是等待的超时时间,即select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回。
注意:在Linux下,select返回之后,timeout参数的值可能会被修改(告诉caller还剩下多少时间)。所以,为了安全起见,下次调用select之前,必须重新初始化timeout参数。

timeout的另外一个常见的用法是用来获得一个亚秒级的延时,下面是例子代码:

点击(此处)折叠或打开

  1. void mysleep(int sec, int usec)
  2. {
  3.     struct timeval tm;
  4.     tm.tv_sec = sec;
  5.     tm.tv_usec = usec;
  6.     select(0, NULL, NULL, NULL, &tm);
  7. }

fd_set 的使用

select的第2~4个参数的类型都是fd_set的指针,fd_set是一组文件描述符的集合,它用一位来表示一个fd。系统提供了4个宏对描述符集进行操作:

点击(此处)折叠或打开

  1. void FD_SET(int fd, fd_set *fdset); //设置文件描述符集fdset中对应于文件描述符fd的位(设置为1)
  2. void FD_CLR(int fd, fd_set *fdset); //清除文件描述符集fdset中对应于文件描述符fd的位(设置为0)
  3. void FD_ZERO(fd_set *fdset); //清除文件描述符集fdset中的所有位(把所有位都设置为0)
  4. void FD_ISSET(int fd, fd_set *fdset); //在调用select后使用FD_ISSET来检测文件描述符集fdset中对应于文件描述符fd的位是否被置位。

注意:
1. select返回之后,fd_set的值可能会被修改(告诉caller那些FD已经ready或者有exception发生)。所以,下次调用select之前,必须重新初始化。
2. OS通过宏FD_SETSIZE来声明在一个进程中select所能操作的文件描述符的最大值(即fd_set包含的bit数),Linux下默认是1024。

阅读(1416) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~