• select函数


    select函数:

    http://baike.baidu.com/view/3421856.htm

    select函数

     

    概况

    select()的机制中提供一fd_set的数据结构,实际上是一long类型的数组, 每一个数组元素都能与一打开的文件句柄(不管是Socket句柄,还是其他 文件或命名管道或设备句柄)建立联系,建立联系的工作由程序员完成, 当调用select()时,由内核根据IO状态修改fd_set的内容,由此来通知执 行了select()的进程哪一Socket或文件可读。
    阻塞式I/O编程有两个特点:
    一、如果一个发现IO有输入,读取的过程中,另外一个也有了输入,这时候不会产生任何反应.这就需要你的程序语句去用到select函数的时候才知道有数据输入。
    二、程序去select的时候,如果没有数据输入,程序会一直等待,直到有数据为止,也就是程序中无需循环和sleep。
    Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如connect、accept、recv或recvfrom这样的阻塞程序(所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必须等待某个事件的发生,如果事件没有发生,进程或线程就被阻塞,函数不能立即返回)。
    可是使用Select就可以完成非阻塞(所谓非阻塞方式non-block,就是进程或线程执行此函数时不必非要等待事件的发生,一旦执行肯定返回,以返回值的不同来反映函数的执行情况,如果事件发生则与阻塞方式相同,若事件没有发生,则返回一个代码来告知事件未发生,而进程或线程继续执行,所以效率较高)方式工作的程序,它能够监视我们需要监视的文件描述符的变化情况——读写或是异常。
    返回值:准备就绪的描述符数,若超时则返回0,若出错则返回-1。

    编辑本段操作程序

    下面具体解释:
    #include <sys/types.h>
    #include <sys/times.h>
    #include <sys/select.h>
    int select(nfds, readfds, writefds, exceptfds, timeout)
    int nfds;
    fd_set *readfds, *writefds, *exceptfds;
    struct timeval *timeout;
    ndfs:select监视的文件句柄数,视进程中打开的文件数而定,一般设为你要监视各文件
    中的最大文件号加一。
    readfds:select监视的可读文件句柄集合。
    writefds: select监视的可写文件句柄集合。
    exceptfds:select监视的异常文件句柄集合。
    timeout:本次select()的超时结束时间。(见/usr/sys/select.h,可精确至百万分之一秒!)
    当readfds或writefds中映象的文件可读或可写或超时,本次select()
    就结束返回。程序员利用一组系统提供的宏在select()结束时便可判
    断哪一文件可读或可写,对Socket编程特别有用的就是readfds。

    编辑本段宏解释

    几行相关的宏解释如下:
    FD_ZERO(fd_set *fdset):清空fdset与所有文件句柄的联系。
    FD_SET(int fd, fd_set *fdset):建立文件句柄fd与fdset的联系。
    FD_CLR(int fd, fd_set *fdset):清除文件句柄fd与fdset的联系。
    FD_ISSET(int fd, fd_set *fdset):检查fdset联系的文件句柄fd是否
    可读写,当>0表示可读写。
    (关于fd_set及相关宏的定义见/usr/include/sys/types.h

    编辑本段socket读写

    这样,你的socket只需在有东东读的时候才读入,大致如下:
    ...
    int sockfd;
    fd_set fdR;
    struct timeval timeout = ..;
    ...
    for(;;) {
    FD_ZERO(&fdR);
    FD_SET(sockfd, &fdR);
    switch (select(sockfd + 1, &fdR, NULL, NULL , &timeout)) {
    case -1:
    error handled by u;
    case 0:
    timeout hanled by u;
    default:
    if (FD_ISSET(sockfd, &fdR)) {
    now u read or recv something;
    /* if sockfd is father and
    server socket, u can now
    accept() */
    }
    }
    }
    所以一个FD_ISSET(sockfd)就相当通知了sockfd可读。
    至于struct timeval在此的功能,请man select。不同的timeval设置
    使select()表现出超时结束、无超时阻塞和轮询三种特性。由于
    timeval可精确至百万分之一秒,所以Windows的SetTimer()根本不算
    什么。你可以用select()做一个超级时钟。
     
     
    开放分类:
    技术软件操作系统
     
     
     
     

    百度百科中的词条正文与判断内容均由用户提供,不代表百度百科立场。如果您需要解决具体问题(如法律、医学等领域),建议您咨询相关领域专业人士。

    142
  • 相关阅读:
    司马光 王安石
    辛弃疾
    伯仲叔季
    三国时代
    西汉 东汉 三国(曹魏 蜀汉 东吴)
    数量关系练习题
    为什么不推荐使用外键约束
    Google Map API申请
    Android传感器——加速度传感器
    第三届空间信息智能服务研讨会
  • 原文地址:https://www.cnblogs.com/gdutbean/p/3256194.html
Copyright © 2020-2023  润新知