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

    读一个文件描述符写另一个文件描述符时迫切需要

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

    readfds,writefds,execptfds 是我们关心的可读可写 和异常的文件描述符集合

    maxfdp1 表示最大文件描述符号+1的数

    tvptr==null  永远等待

    tvptr->tv_sec==0&&tvptr->usec==0  不等待  直接检测

    文件描述符集合需要用一下几个函数:

    int FD_ISSET(int fd,fd_set *fdset);         //检测是否是 打开状态 select 函数返回时候

    void FD_CLR(int fd,fd_set *fdset);    //将某一位关闭

    void FD_SET(int fd,fd_set *fdset);    //将某一位开启

    void FD_ZERO(fd_set * fdset);    //将一个fsd_set 变量所有位设置为0  初始化时候使用

    需要注意的是 每次调用select函数的之前 都需要 初始化和设置fd_set

    void relay(int fd1,int fd2)
    {
        struct fsm_st fsm12,fsm21;
        int fd1_save,fd2_save;
        fd_set rset,wset;    
    
        fd1_save = fcntl(fd1,F_GETFL);//获取文件描述符状态
        fcntl(fd1,F_SETFL,fd1_save|O_NONBLOCK);//加上为阻塞状态
        fd2_save = fcntl(fd2,F_GETFL);
            fcntl(fd2,F_SETFL,fd2_save|O_NONBLOCK);
    
        fsm12.state = STATE_R;
        fsm12.sfd = fd1;
        fsm12.dfd = fd2;
    
        fsm21.state = STATE_R;
        fsm21.sfd = fd2;
        fsm21.dfd = fd1;
    
        while(fsm12.state != STATE_T || fsm21.state != STATE_T)
        {
            /*布置监视任务*/
    
            FD_ZERO(&rset);
            FD_ZERO(&wset);
            
            if(fsm12.state == STATE_R)
                FD_SET(fsm12.sfd,&rset);
            if(fsm12.state == STATE_W)
                FD_SET(fsm12.dfd,&wset);
            if(fsm21.state == STATE_R)
                FD_SET(fsm21.sfd,&rset);
            if(fsm21.state == STATE_W)
                FD_SET(fsm21.dfd,&wset);
    
    
            /*监视*/
            if(fsm12.state < STATE_AUTO || fsm21.state < STATE_AUTO)
            {
                if(select(max(fd1,fd2)+1,&rset,&wset,NULL,NULL) < 0)
                {
                    if(errno == EINTR)
                        continue;
                    perror("select()");
                    exit(1);
                }
            }
            /*查看监视结果*/
            if(FD_ISSET(fd1,&rset) || FD_ISSET(fd2,&wset) || fsm12.state > STATE_AUTO)
                fsm_driver(&fsm12);
            if(FD_ISSET(fd2,&rset) || FD_ISSET(fd1,&wset) || fsm21.state > STATE_AUTO)
                fsm_driver(&fsm21);
        }
    
        fcntl(fd1,F_SETFL,fd1_save);//还原文件描述符状态
        fcntl(fd2,F_SETFL,fd2_save);
        
    }
  • 相关阅读:
    libevent源码学习之event
    游戏寻路A*算法
    游戏地图动态生成
    一个基于protocol buffer的RPC实现
    TCMalloc源码学习(四)(小内存块释放)
    TCMalloc源码学习(三)(小块内存分配)
    TCMalloc源码学习(二)
    第五十四篇 Linux相关——远程连接SSH
    第五十三篇 Linux相关——Web服务器
    第五十二篇 Linux相关——数据库服务MySQL
  • 原文地址:https://www.cnblogs.com/qingducx/p/5205936.html
Copyright © 2011-2022 走看看