关于epoll的进程模型
先描述一下问题背景: 研究过Reactor的同学都知道epoll,小弟最近在写一个Reactor, 然后有一个地方很困惑,以前也想过这个方式。代码如下:
这里是反应堆的核心代码,箭头标明的地方就是我的问题所在。 在epoll返回一个描述符可读或者可写的时候我会把对应的事件放入到一个singalQueue,然后返回后由主进程统一执行对应事件上的回调。因为是无阻塞的,所以这里的处理应该是相当快的。
以前也想过将就绪事件放入到一个线程池里面,由Worker线程异步处理(Nginx使用的是每个进程一个epoll监听并同步处理)。这样主进程直接重新进入epoll_wait, 但是这样会遇到一些问题:
1.就Linux本身的线程模型来看,用户空间和内核空间是1:1的,线程在底层其实和进程是一样的,那么对同一个事件而言,有可能第一次就绪后是由线程1处理,第二次由线程2处理,频繁的切换线程对于同一个套接口描述符的读写会不会引起CPU缓存抖动?
2.和上一个问题很类似,考虑到网卡的中断亲和性设置,就有可能是处理中断的时候是CPU—0,而在用户层这个数据是被线程1执行的,线程1却在CPU-1上执行了读取操作,也就是说可能导致的情况就是,处理中断的CPU和从网卡读取数据的CPU不是同一个,这种情况下SMP体系的CPU的BUFFER是怎么安排的?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于问题1,如果是针对每个线程开一个队列,用个哈希算法把事件固定地分配给每个线程,在请求数较多的情况下,统计上说各核的利用率应该也会比较平均,这样你的问题应该基本可以解决,而且锁的粒度也还顺便减小了;只是实际效果会不会改善不好说。。。
问题2的话,我没有什么想法。底层封装太严实,也许上层就是没办法。。。