当前位置:  技术问答>linux和unix

多路I/O中select机制的问题

    来源: 互联网  发布时间:2015-11-28

    本文导语:  select返回的是某一个文件描述符是否读写,还是好几个呢? FD_ISSET宏是判断一个文件描述符是否在集合里,那它怎么判断一个描述符是否可读写呢?? select机制中,是不是不论从串口、网口、键盘输入的数据都先到...

select返回的是某一个文件描述符是否读写,还是好几个呢?
FD_ISSET宏是判断一个文件描述符是否在集合里,那它怎么判断一个描述符是否可读写呢??
select机制中,是不是不论从串口、网口、键盘输入的数据都先到系统内核中缓存,然后程序处理的时候,到系统内核中读取数据?

请高手指教!

|
man select知道:
    返回正值为发生数据传输的socket数目。0值为timeout。负值为有错误发生。
当然可以好几个文件描述符可读写。只要你当初用FD_SET将你想侦听的socket加入fds_serial中。然后用FD_ISSET来判断所有你加入的socket是否有数据传输,
简单架构就是:
int main()
{
  fd_set rfds;
  struct timeval tv;
  int retval;

//Watch stdin(fd 0) and stderr(fd 2) to see when it has input
  FD_ZERO(&rfds);
  FD_ISSET(0, &rfds);
  FD_ISSET(2, &rfds);
  
//Wait up to five seconds
  tv.tv_sec = 5;
  tv.tv_usec =0;

  retval = select(2, &rfds, NULL, NULL, &tv);

  if(retval  0
  {
      printf("Data is available now.n");
      if(FD_ISSET(0, &rfds))
      {
         printf("stdin has data inn");
         //read_stdin_data();
         exit(0);
      }
      if(FD_ISSET(2, &rfds))
      {
         printf("stderr has data inn");
         //read_stderr_data();
         exit(0);
      }
  }
}

|
linux里的select自己就是一个循环,每次执行时检查是否有描述符就绪或出现异常,如果都没有就主动让出cpu,自己小睡一会儿,这个睡眠可能被I/O动作结束后的信号打断,也可能睡足一个时间后主动醒来,然后再次执行检查。如果有描述符就绪或者error发生,则置fd_set中相应位,全部检查完后,fdset不为空,于是select返回到程序中。

|
多路复用,我理解就象是几个描述符并行操作,既然是并行,当然是有可能几个同时到达可读写的条件的。
其实select中用了一个int,也就是32bit来保存你感兴趣的描述符的状态,初始状态32位都位0;当某个描述符变为可读写的时候,其对应的位就被设置位1。select本身是一个循环,当一个循环到来时,它来检测这32位中有几个1。从一次循环到下次循环总有一段时间,这段时间就有可能有几个描述符都变为了可读写了。

|
select返回后有几种不同含义
任何描述字准备好读或写,有异常等待处理,超时,
如果你在执行select之前,初始化了集合多个位,返回值表示跨所有描述字集的已准备好的总位数(不考虑异常和超时)

“数据都先到系统内核中缓存”,只知道是先读到套接口缓冲区

|
当select返回后,要用FD_ISSET判断每一个字集
存放在套接口缓冲区,要用接收函数去获取

|
select()函数可以一次返回多个活动的描述符,参数中输入的是你所关心的描述符的列表,返回后,里边保存的是活动的描述符的列表。

|
该函数允许进程指示内核等待多个时间中的任何一个发生,并且仅在一个或多个时间发生或者经过某指定时间后才唤醒进程。通过select()的产如参数,我们可以通知内核我们对哪些描述字感兴趣(读、写或者异常情况)以及等待多长时间,我们所关心的描述字不受限与套接字,任何描述字都可以用select()函数进行测试。
可以运用一下测试宏对描述符列表进行设置和测试:
 FD_CLR(int fd, fd_set *set);
  FD_ISSET(int fd, fd_set *set);
  FD_SET(int fd, fd_set *set);
  FD_ZERO(fd_set *set);

    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 如何实现多路复用?
  • JMF中如何实现多路音频的混合输出?期待高手指教!
  • epoll多路复用模型的疑惑,请高手解答
  • 多路播放器的问题,问题解决了补加100分,请各位大哥指教
  • 关于LINUX有名管道的多路复用问题


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3