IO多路复用形象举例

发布时间 2023-03-26 20:08:46作者: ZqurGy

IO多路复用的形象举例

IO多路复用意义

  • 接着上面的例子,IO多路复用的作用就是为了管理这些服务员,以便于提供点菜的服务
  • 方法1:select‘

    • 找一个人专门去咨询,拿着三个本记录三个状态:点菜、点酒、结账
      • select(服务员的数量,点菜的集合,点酒的集合,结账的集合,问一次多长时间);
      • select返回后拿到对应的集合
    • select(ionum, rfds, wfds, efds, timeout);
    ionum-》这个位置的值是maxfd+1,因为文件描述符是int类型并且是依次增加的,所以最大的fd+1就可以直到fd的数量
    timeout-》跑一次select是多久-》会在函数内部进行阻塞,最多等待timeout秒,如果遍历完毕有结果立即返回,否则最多等待设置的秒数
    
  • 方法2:poll

    • 方法1的基础上使用一个本记三个状态
    • poll(pfd, length, timeout);
      • pfd是队列头的指针,需要提前进行赋值
      • timeout和select类似,内部阻塞时间
  • 方法3:epoll-》epoll源码位置:../fs/eventpoll.c

    • 新的例子:一个小区里有N多个用户,小区旁有个蜂巢,快递通过蜂巢来进行送取快递
    • 快递员-》epoll_create(int size);
    • 小区用户数量的增加、减少和改变-》epoll_ctl(ADD/DEL/MODIFY);
    • 送取一次快递的允许时间epoll_wait(快递员, 快递员的袋子, 袋子的大小, 阻塞时间);

    • epoll_creat()

      epoll_create(int size);

      • size 的状态只有0或者1,只有>0的值都相当于1,所以多大都没有意义,以前是用于指定内核维护的队列大小
    • epoll_ctl()

      • epoll_ctl(epfd, op, fd, event);
    • epoll_wait()

      • epoll_wait(epfd, evlist, maxevents, timeout);
    • epoll的ET和LT

      • ET( Edge Trigger):边沿触发
        • 无论读缓存中有没有数据,只有收到一次数据才会触发一次epoll_wait,把数据带出来
      • LT( Level Trigger):水平触发
        • 只要读缓存中有数据,有数据就会一直触发epoll_wait,把数据带出来
      • ET+循环读 == LT+一次性读 等价
    • 如何选择ET和LT?

      • 大块的数据读-》LT
        • listen的fd适合用LT-》一次性来多个连接的情况
      • 小块的数据读-》ET
        • 由于ET+循环读只针对一个IO,会导致占用过多的时间,不太合适大块数据