fd_set和select函数

文件描述符

  • 在Linux中,内核利用文件描述符即文件句柄,来访问文件。打开现存文件或新建文件时,内核会返回一个文件描述符,读写文件也需要使用文件描述符来指定待读写的文件。

  • 文件描述符是非负整数。

fd_set结构体

fd_set可以理解为一个集合,这个集合中存放的是文件描述符即文件句柄。

fd_set集合可以通过下面的宏来进行人为来操作。

1、FD_ZERO
	用法:FD_ZERO(fd_set*);
	用来清空fd_set集合,即让fd_set集合不再包含任何文件句柄。

2、FD_SET
	用法:FD_SET(int ,fd_set *);
	用来将一个给定的文件描述符加入集合之中

3、FD_CLR
	用法:FD_CLR(int ,fd_set*);
	用来将一个给定的文件描述符从集合中删除

4、FD_ISSET
	用法:FD_ISSET(int ,fd_set*);
	检测fd在fdset集合中的状态是否变化,当检测到fd状态发生变化时返回真,否则,返回假(也可以认为集合中指定的文件描述符是否可以读写)。

select函数

用来监视需要监视的文件描述符(读或写的文件集中的文件描述符)的状态变化情况。并能通过返回的值告知我们。

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

timeval的结构定义如下:

struct timeval{
	long tv_sec;	//秒
	long tv_usec;	//微秒
}

参数介绍

int maxfdp:					集合中所有文件描述符的范围,为所有文件描述符的最大值加1。
fd_set* readfds:			要进行监视的读文件集。
fd_set* writefds :			要进行监视的写文件集。
fd_set* errorfds:			用于监视异常数据。
struct timeval* timeout:	超时时间,它可以使select处于三种状态:
	- NULL: 阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止
	- 0:	纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值
	- 大于0: 等待的超时时间,在timeout时间内阻塞,未超时如果有事件到来就返回,否则在超时后不管怎样一定返回

返回值

>0:被监视的文件描述符有变化; 返回就绪的文件描述符个数

-1:出错, 并设置errno

0 :超时;经过了timeout时长后仍无设备准备好,返回值为0

select调用返回时,除了那些已经就绪的描述符外,select将清除readfds、writefds和exceptfds中的所有没有就绪的描述符。

相关问题

如果select调用中设置了等待时间,那么每次调用时都需要重新对这个时间赋值么?

fd_set readfd;
struct timval tv;

while(1) {
  FD_ZERO(&readfd);
  FD_SET(fd, &readfd);
  tv.tv_sec = 2;
  tv.tv_usec = 0;
  select(maxfd+1, &readfd, NULL, NULL, &tv);
  ......;
}

不可以, 因为tv在函数内部被改变了,时间会越来越来少,所以每次都要重新被赋值。

这个函数真是神通广大,用来定时也不错。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值