epoll与select
最后更新于:2022-04-02 04:09:36
[TOC]
## 思考
场景:有100W个 socket连接需要处理。
思考:
- linux下 socke连接抽象成了文件(100W个文件句柄)
- 系统其实就是在不断检查100W个文件中有没有数据到来
- 100W个 socket并发很高要,稍有不慎,就造成系统雪崩
## 解决办法
### 阻塞 I/O(不推荐)
开启100w个线程
```
while(read(sockets[i])){
// do something
slepp(1)
}
```
### 多路复用(方案一,单也不推荐)
把100w个链接分成1000组,只需要1000个线程
### select/poll
```
for(fd:fds){
if(somethingln{(fd)){
read()
}
}
```
图示:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/b7/4b/b74baf2af62d61cc9d8ba2aaebdd9493_400x304.png)
select/pol模型是同步还是异步?
- select/po发生后,交由内核执行,直到有接收数据的通知出现。因此是异步模型。
selec/pol型是阻塞还是非阻塞?
- select/pol发生后,线程会被阻塞(进入阻塞状态),因此是阻塞模型。
### epoll
#### 处理 100w 数据量-insert,delete,find
既然允许增加操作內核中的fd,那么如何确保所有操作insert find. delete都在o(1)
- 数组: insert~O(m),find~O(n), delete~O(n)
- 链表: insert~O(1),find~o(m), delete~O(1)
- HashTable:100W数据量(100W整数),效果不好— HashTable适合全集很大,但是抽样很小的场景
- 平衡的树(如二叉搜索树红黑树
- insert O(lgn)
- delete O(lgn)
- find o(lgn)
> 使用平衡数进行管理,被称为 epoll 方案
说明:
- 增量向内核传输FD(同理,增加删除FD)
- 内核返回事件(而不是FD)
- 事件中带有可以被读取的FD(避免线程遍历
';