Poll

作者: 吃掉夏天的怪物 | 来源:发表于2021-04-14 14:06 被阅读0次

    Linux下有三种I/O复用模型,select、poll、epoll

    为什么要用I/O复用模型呢?

    计算机资源有限,线程号也有限。如果一个线程管理一个I/O请求,在I/O请求很多的时候并不能适应。
    用I/O复用模型就可以一个线程管理多个I/O。

    poll函数原型.png
    poll使用基本流程.png

    按这个流程写的只能称之为 玩具代码,可能出现一些问题

    1.read 可能并没有把connfd所对应的接收缓冲区的数据都读完,那么connfd仍然是活跃的

    • 这本身是没有问题的,但是应用层发送过来的数据包,刚好分包了。一个数据包,两次read才能接收完全的话,就可能会发生粘包问题。
      我们应该将读到的数据保存在connfd的应用层接收缓冲区。

    2. write 如果发送缓冲区满了 write并不能把所有数据都发送

    write发送的时候,我们也应用有一个应用层的发送缓冲区。

    POLLOUT事件 触发条件,connfd的发送缓冲区不满(可以容纳数据了)
    (如果一开始就关注POLLOUT事件可能会出现,忙等待)

    (POLL 其实也是LT 电平触发,不支持ET。EPOLL和POLL 的LT 一样)

    EMEFILE处理.png

    最可取的是,最后一种处理方式。


    image.png

    (先接收过来,再断开避免busy loop)

    Linux网络编程 第12讲 tcp11种状态中
    如果客户端关闭套接字close
    而服务器,调用了一次write,服务器会接收到一个RST segment(TCP传输层)
    如果服务器再次调用了write,这个时候就会产生 SIGPIPE信号。(如果没有忽略这个信号的话,这个信号的默认方式就是推出我们的进程)

    TIME_WAIT状态 对大并发服务器的影响

    应该尽可能在服务器端避免出现TIME_WAIT状态
    什么时候会出现TIME_WAIT状态呢?
    如果服务器端 主动断开连接(先于client调用close),之后服务器端就会进入TIME_WAIT。这样的话在内核中就会hook住一些单元,并发能力下降。

    协议设计上,应该让客户端主动断开连接,这样就把TIME_WAIT状态分散到大量的客户端。
    如果客户端不活跃了,一些恶意客户端不断开连接,这样就会占用服务器的连接资源。
    服务器端也要有一个机制来踢掉不活跃的的连接 close

    man socket
    man fcntl

    nonblocking socket + I/O复用


    image.png

    C++ 11 第一个元素首地址可以这么写polldfs.data(); -1表示永远等待

    image.png
    image.png

    cmake

    sudo apt-get install cmake
    需要配置一个 CMakeList.txt文件
    cmake .当前CMakeList.txt所在目录
    编译出来的可执行文件在bin目录下

    set_-x shell编程的知识
    Linux编程知识得学一下

    相关文章

      网友评论

        本文标题:Poll

        本文链接:https://www.haomeiwen.com/subject/alszkltx.html