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(避免线程遍历
';