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