select函数的一些总结

 函数原型:int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);

参数说明:fd_set 是一个结果体struct fd_set,该结构是一个文件描述符集合;

struct timeval是一个关于时间设置的结构体:

struct timeval

{

time_t tv_sec;/*seconds*/

suseconds_t tv_usec;/*microseconds*/

}

参数意义:readfds 指向读文件描述集合,用来监控这个集合中是否有描述符可以读;writefds指向写文件描述集合,用来监控这个集合中是否有描述符可以写;errorfds用来监视文件错误异常。

Maxfdp 是所有打开的文件描述中最大的那个再加上1

Timeout

1)当它为NULL的时候,表示select一直处于阻塞状态,直到readfdswritefdserrorfds这三个集合中有一个状态发生了改变selcet函数才返回。

2)当它为{00}时,表示select处于非阻塞状态,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值。

3)当它设置了时间值时(如3妙),如果在设置的时间内没有状态改变则select函数返回0,表示超时。

Select函数的返回值:

(1)       小于0表示调用select出错了

(2)       等于0表示设置了超时了

(3)       大于0(返回文件描述词状态已改变的个数)表示要监控的三个集合中有一个状态发生了改变有文件描述符可读可写或者出错了。此时参数readfdswritefdsexceptfdstimeout的值变成不可预测。

EBADF 文件描述词为无效的或该文件已关闭
EINTR
此调用被信号所中断
EINVAL
参数n 为负值。
ENOMEM
核心内存不足

 

关于select有几个宏:

FD_ZERO(fd_set* set) //清空集合set中的文件描述

FD_SET(int fd, fd_set* set) //将文件描述符加入到集合set中去

FD_CLR(int fd, fd_set* set) //将文件描述符从集合set中清除

FD_ISSET(int fd, fd_set* set) //判断集合set中的文件描述符fd是否为真(状态发生改变)

 

#include <sys/time.h> //need time
#include <stdio.h> //need io input and output
#include <sys/types.h> //type define
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <time.h>

int main ()
{
 int keyboard;
 int ret, i;
 char str[10];
 fd_set readfd;
 time_t select_start_time, select_end_time;

 struct timeval timeout;
 /*ÉèÖó¬Ê±µÄʱ¼äΪ3Ãë*/
 timeout.tv_sec = 5;
 timeout.tv_usec = 0;
 
 /*´ÓÖն˶ÁÈ¡Êý¾Ý*/
 keyboard = open("/dev/tty", O_RDONLY | O_NONBLOCK);
 /*±£Ö¤ÖÕ¶ËÕýÈ·´ò¿ªÁË*/
 assert(keyboard > 0);
 
 while(1)
 {
  /*½«¼¯ºÏreadfdÖеÄÎļþÃèÊö·ûÇåÁã*/
  FD_ZERO(&readfd); 
  /*½«ÎļþÃèÊö·û¼ÓÈ뼯ºÏreadfdÖÐ*/
  FD_SET(keyboard, &readfd);
  /*¼ì²â¶Á¼¯ºÏÖÐÊÇ·ñÓÐÊý¾Ý¿É¶Á*/
  time(&select_start_time);
  ret = select(keyboard+1, &readfd, NULL, NULL, &timeout);
  /*ÔÚ3ÃîÖ®ÄÚ¼à¿ØµÄÎļþÃèÊö·ûÓÐÊý¾Ý¿É¶Á*/
  if (ret > 0)
  {
   /*Åжϼ¯ºÏreadfdÖеÄÎļþÃèÊö·ûkeyboardÊÇ·ñÓÐÊý¾Ý¿É¶Á*/
   if (FD_ISSET(keyboard, &readfd))
   {
    /*¶ÁÈ¡9¸ö×Ö½ÚµÄÊý¾Ý,Èç¹ûûÓÐ9¸ö×Ö½ÚµÄÊý¾Ý¾Í¶Áȡʵ¼ÊµÄ×Ö½ÚÊý£¨Èç3¸ö£©*/
    i = read(keyboard, str, 9);
    /*×Ö·û´®Ä©Î²¼Ó\0*/
    str[i] = '\0'; 
    printf("get data from tty is %s\n", str);
     }
  }
  /*Ôڹ涨µÄʱ¼äÄÚûÓÐÊý¾Ý¿É¶Á£¨³¬Ê±ÁË£©*/
  else if ( ret == 0)
  {
   printf("select time out\n");
   break;
  }
  /*µ÷ÓÃselectº¯Êý³ö´íÁË*/
  else
  {
   printf("select error\n");
   break;
  } /*end if*/
 } /*end while*/ 

 time(&select_end_time);
 printf("select run time is %d\n", (select_end_time - select_start_time));
} /*end main*/

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值