多路复用的select()和poll()函数总结

   作为游戏于linux的新手,记录下学习旅程还是挺有味道。不仅要学习专业课程,还挤出时间来玩弄LINUX,虽然忙了点,不过能够记录点点滴滴的进步,还是幸福的旅程啊···

Linux下的多路复用技术。所谓多路复用,感性的概念就不赘述。简单小结下linux多路复用中的些知识。常用的多路复用函数:select()poll()

int select(int maxfdp1, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict exceptfds,     struct timeval *restrict tvptr); 

fd_set *restrict readfds, // 关注的读fd   即:我们是要监视这些文件描述符的读变化的,即我们关心是否可以从这些文件中读取数据了,如果这个集合中有一个文件可读,select就会返回一个大于0的值,表示有文件可读,如果没有可读的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,select返回0,若发生错误返回负值。传入NULL值,表示不关心任何文件的读变化。以下两者类似。
    fd_set *restrict writefds, // 关注的写fd
    fd_set *restrict exceptfds, // 关注的异常fd

对数据类型fd_set操作有如下四个宏:

fd_set set;

    FD_ZERO(&set);       /* set清零使集合中不含任何fd*/

    FD_SET(fd, &set);    /* fd加入set集合 */

    FD_CLR(fd, &set);    /* fdset集合中清除 */

    FD_ISSET(fd, &set); /* 测试fd是否在set集合中*/ 


int maxfdp1是文件描述符集中的最大文件描述符加1。。。  所谓文件描述符集,即fd_set,过去,一个fd_set通常只能包含<32fd(文件描述),因为fd_set其实只用了一个32位矢量来表示fd;现在,UNIX系统通常会在头文件<sys/select.h>中定义常量FD_SETSIZE,它是数据类型fd_set的描述字数量,其值通常是1024,这样就能表示<1024fd。根据fd_set的位矢量实现,我们可以重新理解操作fd_set的四个宏:

    fd_set set;

FD_ZERO(&set);      /*set的所有位置0,如set在内存中占8位则将set置为

00000000*/

FD_SET(0, &set);    /* set的第0位置1,如set原来是00000000,则现在变为10000000,这样fd==1的文件描述字就被加进set中了 */

FD_CLR(4, &set);    /*set的第4位置0,如set原来是10001000,则现在变为10000000,这样fd==4的文件描述字就被从set中清除了 */

FD_ISSET(5, &set); /* 测试set的第5位是否为1,如果set原来是10000100,则返回非零,表明fd==5的文件描述字在set中;否则返回0*/

*****  注意:fd的值必须小于1024  ****

///该函数测试单个文件描述符是否具可读性的例子:://

       int isready(int fd)

     {

         int rc;

         fd_set fds;

         struct timeval tv;    

         FD_ZERO(&fds); //清空文件描述符集//

         FD_SET(fd,&fds);//将文件描述符fd加入到文件描述符集fds//

         tv.tv_sec = tv.tv_usec = 0;    //时间设为0,使函数检查完fd后立即返回//

     rc = select(fd+1, &fds, NULL, NULL, &tv);

         if (rc < 0)   //error

           return -1;    

         return FD_ISSET(fd,&fds) ? 1 : 0;//测试fd是否在fds集中。是则返回1//

     }

类似地,可以修改该程序,测试单个文件描述符是否具可写性,也可加入循环,测试一个文件描述符集中的文件描述符是否具可读或可写性。

//

//下面总结下poll函数,即轮询的用法///

select()poll()本质上来讲做的是同一件事,只是完成的方法不一样。两者都通过检验一组文件描述符来检测是否有特定的时间将在上面发生并在一定的时间内等待其发生。

*******************************************************************************************注意:无论select()还是poll()都不对普通文件起很大效用,它们着重用于套接口(socket)、管道(pipe)、伪终端(pty)、终端设备(tty)和其他一些字符设备,但是这些操作都是系统相关(system-dependent)的。**********************************************************************************************poll()接受一个指向结构'struct pollfd'列表的指针,其中包括了你想测试的文件描述符和事件

 struct pollfd {
         int fd;        /* 文件描述符 */
         short events;  /* 等待的事件 */
         short revents; /* 实际发生了的事件 */
     };

函数原型:int poll(struct pollfd *fds ,int numfds,int timeout);

nfds 说明我们关心的文件描述的个数,即struct pollfd 结构所指数组中的元素数目

timeoutpoll函数调用阻塞的时间,单位:毫秒;若小于等于0,则无限等待。

返回值:大于0,成功,表示事件发生的pollfd结构的个数;;

          0,超时;;

         -1:出错

Poll()函数比select()函数的运行效率更高。通过获得时间的函数计算程序可比较两者的运行时间.相应函数之后再总结了。。。

///



     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值