select详解

#inlcude <sys/select.h>


int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds,

                             fd_set *restrict errorfds, struct timeval *restrict timeout);

参数:nfds给出了要监视的文件描述符的范围,其值至少比最大的文件描述符值大1.

          readfds, writefds, errorfds分为为读操作,写操作和错误情况监视的文件描述符集,文件描述符集类型为fd_set。

          timeout超时值,经过一段时间后, 即使没有准备就绪的描述符,他也会迫使select返回。timeout为NULL

         时,select可能会无限期地阻塞。

返回: 成功时,返回已准备就绪的文件描述符的个数,并清空除已准备就绪的描述符之外

            readfds,writefds,errorfds   中的所有描述符; 不成功,返回-1 并设errno。

必须设置的errno:

EBADF                       一个或多个文件描述符集指定了无效的文件描述符 

EINTR                       在超时或被选中的时间发生之前被select信号中断

EINVAL                   指定了一个无效的超时时间,或者nfds小于0或大于FD_SETSIZE


描述符集用比特掩码来实现。

相关函数:

void FD_CLR(int fd, fd_set *fdset);//清除fd对应的比特位

void FD_ISSET(int fd, fd_set *fdset);//测试fd对应的比特位是否被设置,被设置表示文件描述符存在

void FD_SET(int fd, fd_set *fdset);//设置fd对应的比特位

void FD_ZERO(fd_set *fdset);清楚fdset中所有的比特位


例子代码:

//用select进行两个并发文件拷贝的函数

#include <errno.h>

#include <stdio.h>

#include <string.h>

#include <sys/time.h>


int copy2files(int fromfd1, int tofd1, int fromfd2, int tofd2)

{

        int bytesread, maxfd, num, totaltytes = 0;

        fd_set readset;


        if ((fromfd1 < 0) || (fromfd1 >= FD_SETSIZE) ||

            (tofd1 <0)      || (tofd1     >= FD_SETSIZE) ||

            (fromfd2 < 0) || (fromfd2 >= FD_SETSIZE) ||

             (tofd2 <0)    ||  (tofd2       >= FD_SETSIZE) )

         return 0;

       maxfd = fromfd1;                   //找到最大的描述符

       if (fromfd2 > maxfd)

            maxfd = fromfd2;

      

       for (; ; )

       {

           FD_ZERO(&readset);

           FD_SET(fromfd1, &readset);

          FD_SET(fromfd2, &readset);

          if ((num = select(maxfd+1, &readset, NULL, NULL, NULL)) == -1) && (errno == EINTR))

                 continue;

          if (num == -1)

           return totalbytes;

         if (FD_ISSET(fromfd1, &readset))

          { 

             bytesread = readwrite(fromfd1, tofd1);

             if (bytesread <= 0)

             break;

             totalbytes += bytesread;

          }

          if (FD_ISSET(fromfd2, &readset))

          { 

             bytesread = readwrite(fromfd2, tofd2);

             if (bytesread <= 0)

             break;

             totalbytes += bytesread;

          }

       }

       return totalbytes;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值