zoukankan      html  css  js  c++  java
  • IO复用

    IO复用:使得程序能同时监听多个文件描述符

    select:

    select在一段指定的时间内,监听用户感兴趣的文件描述符的 读、写、异常事件。

    select(int nfds,fd_set* readfds ,fd_set* writefds,fd_set* exceptfds,struct timeval* timeout);
    

    当调用了select之后整个进程就会被block。同时kernel会监听select负责的所有的socket.如果
    相关的时间就绪就会返回。

    但是select只能处理 读、写、异常事件,不能处理更多的事件。
    而且内核是对fd_set集合在线修改,下次调用不得不重置相应的集合。。。


    poll:

    int poll(struct pollfd* fds,....);
    

    与select不同的是poll将 文件描述符和时间集合都定义在了 结构体中。并且注册事件和实际发生事件
    被分开了。

    struct pollfd
    { 
        int fd;
        short events;   //注册事件
        short revents;   //实际发生事件
    }
    

    于是每次内核修改的是revents,无需重置pollfd了。


    epoll:

    epoll将用户关心的文件描述符放在内核的一个事件表中,从而无须每次重复传递。但需要一个额外的文件描述符
    来标志内核中的时间表

    epoll_create(int size)             //创建一个事件表
    epoll_ctl()                          //给文件符指定操作类型(注册xxx上的xxx事件...)
    epoll_wait()                         //等待事件
    

    三种方法差异:

    select和poll都只能工作在相对低效的LT模式中,epoll则能在ET模式中并支持EPOLLONESHOT。
    select和poll采用的轮询的方式,每次调用都要扫描整个事件表O(n),而epoll采用的是回调,如果检测到
    就绪的,回调函数就将对应时间插入内核就绪队列中,最后直接拷贝出来O(1)。
    如果触发频繁,epoll的效率不一定高。所以epoll适合连接数量多,活动少的情况。


    LT和ET:

    1.LT(电平模式):
    当epoll_wait检测到事件发生,程序可以不立即处理,再次调用还会出现此事件,直到事件被处理。

    2.ET(边沿触发):
    当epoll_wait检测到事件发生,程序必需立即处理,因为再次调用不会出现。


    EPOLLONESHOT事件:

    即便使用ET,一个事件还是可能被多次触发。
    比如一个线程读取完某个socket上的数据并进行处理时,socket又出现新的数据可读。。。
    此时另一个线程会被唤醒来处理这个。
    如果希望任意时刻一个socket只被一个线程处理,可以使用epoll的EPOLLONESHOT

    参考:

    linux高性能服务器编程

  • 相关阅读:
    Flutter中的剪裁
    flutter设置沉浸式状态栏
    flutter设置主题色和状态栏颜色
    Flutter更改状态栏颜色
    前端基础之JavaScript
    前端基础之CSS
    前端基础之初识 HTML
    socket及其相关(续篇)
    初识socket
    面向对象及其相关
  • 原文地址:https://www.cnblogs.com/Przz/p/6590857.html
Copyright © 2011-2022 走看看