zoukankan      html  css  js  c++  java
  • I/O多路转接模型

    I/O多路转接模型:
        在这种模型下,如果请求的I/O操作阻塞,且它不是真正阻塞I/O,而是让其中的一个函数等待,在这期间,I/O还能进行其他操作。

    #include <sys/select.h>
    #include <sys/time.h>
    int select(int maxfd, fd_set *readset, fd_set *writeset, fd_set *exceptionset, const struct timeval* timeout);   \返回:就绪描述字的正数目,0——超时,-1——出错

    参数解释:
    maxfd            最大的文件描述符(其值应该为最大的文件描述符字 + 1)
    readset          内核读操作的描述符字集合
    writeset         内核写操作的描述符字集合
    exceptionset     内核异常操作的描述符字集合
    timeout          等待描述符就绪需要多少时间。NULL代表永远等下去,一个固定值代表等待固定时间,0代表根本不等待,检查描述字之后立即返回。

    其中 readset、writeset、exceptionset 都是 fd_set 集合。该集合的相关操作如下:
    void FD_ZERO(fd_set *fdset);               /* 将所有fd清零 */
    void FD_SET(int fd, fd_set *fdset);        /* 增加一个fd */
    void FD_CLR(int fd, fd_set *fdset);        /* 删除一个fd */
    int FD_ISSET(int fd, fd_set *fdset);       /* 判断一个fd是否有设置 */

    一般来说,在使用select函数之前,首先要使用FD_ZERO和FD_SET来初始化文件描述符集,在使用select函数时,可循环使用FD_ISSET测试描述符集,在执行完对相关文件描述符之后,使用FD_CLR来清除描述符集(也可以直接用FD_ZERO直接全部清零)。


    select函数中的 timeout 是一个 struct timeval 类型的指针,该结构体如下:
    struct timeval
    {
            long tv_sec;         /* second */         //秒
            long tv_usec;        /* microsecond */    //微秒
    };


    流程:

    fd_set readset;
    FD_SET(0,&readset);
    FD_SET(fdr,&readset);
    int ret=select(fdr+1,&readset,NULL,NULL,NULL);
    if(ret >0)
    {
         if(FD_ISSET(0,&readset))
         {
         }
         if(FD_ISSET(fdr,&readset))
         {
         }
    }

    select 监控哪些描述符可以读

    a.c b.c
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<fcntl.h>
    #include<sys/time.h>
    #include<unistd.h>
    #include<stdio.h>
    #include<strings.h>
    #include<string.h>
    int main(int argc,char** argv)
    {
            int fdw=open(argv[1],O_RDWR);
            int fdr=open(argv[2],O_RDWR);
            printf("fdw=%d fdr=%d ",fdw,fdr);
            char buf[128]="";
            fd_set rdset;
            int ret;
            while(1)
            {
                    FD_ZERO(&rdset);
                    FD_SET(0,&rdset);
                    FD_SET(fdr,&rdset);
                    ret=select(fdr+1,&rdset,NULL,NULL,NULL);
                    if(ret>0)
                    {
                            if(FD_ISSET(0,&rdset))
                            {
                                    bzero(buf,sizeof(buf));
                                    read(0,buf,sizeof(buf));
                                    write(fdw,buf,strlen(buf)-1);  //从控制终端读的时候,回车也会读进去,所以要-1去掉回车
                            }
                            if(FD_ISSET(fdr,&rdset))
                            {
                                    bzero(buf,sizeof(buf));
                                    read(fdr,buf,sizeof(buf));
                                    printf("b:%s ",buf);
                            }
                    }
            }
            return 0;
    }
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<fcntl.h>
    #include<sys/time.h>
    #include<unistd.h>
    #include<stdio.h>
    #include<strings.h>
    #include<string.h>
    int main(int argc,char** argv)
    {
            int fdr=open(argv[1],O_RDWR);
            int fdw=open(argv[2],O_RDWR);
            printf("fdr=%d fdw=%d ",fdr,fdw);
            char buf[128]="";
            fd_set rdset;
            int ret;
            while(1)
            {
                    FD_ZERO(&rdset);
                    FD_SET(0,&rdset);
                    FD_SET(fdr,&rdset);
                    ret=select(fdr+1,&rdset,NULL,NULL,NULL);
                    if(ret>0)
                    {
                            if(FD_ISSET(0,&rdset))
                            {
                                    bzero(buf,sizeof(buf));
                                    read(0,buf,sizeof(buf));
                                    write(fdw,buf,strlen(buf)-1);
                            }
                            if(FD_ISSET(fdr,&rdset))
                            {
                                    bzero(buf,sizeof(buf));
                                    read(fdr,buf,sizeof(buf));
                                    printf("a:%s ",buf);
                            }
                    }
            }
            return 0;
    }

     
  • 相关阅读:
    WINCE基于CH7024实现TV OUT (VGA)功能
    Hello China操作系统在Virtual PC上的安装和使用
    内心独白之程序员思维
    物联网操作系统的架构和基本功能
    说不懂Android系统构架,太亏了!
    Hello China V1.75版本运行截图
    剥开ios 系统sandbox神秘面纱
    Android基础之广播
    《大象Thinking in UML 第二版》已于近日在当当首发,同时邀请各位加入新浪微博[大象thinkinginUml群]:http://q.weibo.com/1483929
    物联网操作系统随笔
  • 原文地址:https://www.cnblogs.com/meihao1203/p/8443979.html
Copyright © 2011-2022 走看看