IO多路复用

 

Select函数使我们可以执行I/O多路转接,传向select的参数告诉内核:

1、我们所关心的描述法

2、对于每个描述符我们关心的状态

3、愿意等待的时间

4、已准备好的描述符的数量

5、对于读写或异常三个状态中的哪一个已准备好

函数原型:

Int select(int maxfdp1,fd_set *readfds,fd_set *writefds,fd_set *exeptfds,struct timeval *timeout)

/*

**主要实现通过调用select函数监听3个终端输入,并分别做相应的处理,

建立了3个读文件描述符,通过监视主程序的虚拟终端标准输入来实现程序的控制,

以两个管道昨为数据输入,主程序将从两个管道读取输入数据写入到标准输出文件

*/

 

/*multiplex_select*/

#include<fcntl.h>

#include<stdio.h>

#include<unistd.h>

#include<stdlib.h>

#include<time.h>

#include<sys/select.h>

#include<errno.h>

#define  IN_FILES       3                   /*多路复用输入文件数目*/

#define MAX(a,b)       ((a>b)?(a):(b))

#define TIME_DELAY 60

#define MAX_BUFFER_SIZE 1024

int main(void)

{

       int fds[IN_FILES];

       char buf[MAX_BUFFER_SIZE];

       int maxfd;

       int i,res;                                           //res是返回准备好的文件描述符数目

       fd_set inset,tmp_inset;                          //声明读集合描述符

       struct timeval tv;

       int real_read;

       /*首先以只读非阻塞方式打开两个管道文件*/

       fds[0]=0;

       if((fds[1]=open("in1",O_RDONLY | O_NONBLOCK))<0)

       {

              printf("open in1 error\n");

              return 1;

       }

       if((fds[2]=open("in2",O_RDONLY | O_NONBLOCK))<0)

       {

              printf("open in2 error\n");

              return 1;

       }

      

       /*取出两个文件描述符中的较大者*/

       maxfd=MAX(MAX(fds[0],fds[1]),fds[2]);

      

       /*初始化读集合inset,并在读集合汇总加入相应的描述符集*/

       FD_ZERO(&inset);

       for(i=0;i<IN_FILES;i++)

       {

              FD_SET(fds[i],&inset);

       }

       FD_SET(0,&inset);

       tv.tv_sec=TIME_DELAY;

       tv.tv_usec=0;

      

       /*循环测试该文件描述符是否准备就绪,并调用select函数对相关文件描述符做对应操作*/

       while(FD_ISSET(fds[0],&inset) || FD_ISSET(fds[1],&inset) || FD_ISSET(fds[2],&inset))

       {

              /*文件描述符集合的备份,这样可以避免每次进行初始化*/

              tmp_inset=inset;

              res=select(maxfd+1,&tmp_inset,NULL,NULL,&tv);

              switch(res)

              {

                     case -1:

                     {

                            printf("Select error\n");

                            return 1;

                     }

                     break;

                     case 0:          /*超时*/

                     {

                            printf("Time out\n");

                            return 1;

                     }

                     break;

                     default:

                     {

                            for(i=0;i<IN_FILES;i++)

                            {

                                   if(FD_ISSET(fds[i]),&tmp_inset)

                                   {

                                          memset(buf,0,MAX_BUFFER_SIZE);

                                          real_read=read(fds[i],buf,MAX_BUFFER_SIZE);

                                          if(real_read<0)

                                          {

                                                 if(errno !=EAGIN)

                                                        return 1;

                                          }

                                          else if(!real_read)

                                          {

                                                 close(fds[i]);

                                                 FD_CLR(fds[i],&inset);

                                          }

                                          else

                                          {

                                                 if(i==0)

                                                 {

                                                        /*主程序终端控制*/

                                                        if((buf[0]=='q') || buf[0]=='Q')

                                                        return 1;

                                                 }

                                                 else

                                                 {

                                                        /*显示管道输入字符串*/

                                                        buf[real_read]='\0';

                                                        printf("%s",buf);

                                                 }

                                          }

                                   }

                            }

                     }

                     break;

              }

             

       }

       return 0;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值