关于 epoll

2015-02-09 21:24:14 +08:00
 josephok
个人理解是epoll可以同时监听多个I/O事件, 但是在处理就绪事件时仍然会发生阻塞。
比如:

https://gist.github.com/josephok/7f0e782a687c603ab4a5

https://gist.github.com/7f0e782a687c603ab4a5.git

在第39行,如果有个task需要执行1000s,那么这个时候进程就会阻塞在这里,其他客户得不到响应。所以需要将这个task变成异步的。比如:


`executor.submit(task)`


这时就不会阻塞,server进程可以继续响应其他客户。

不知道有没有更好的办法?

大家在处理这种问题时一般使用什么方法?
2874 次点击
所在节点    Python
5 条回复
neoblackcap
2015-02-09 23:30:41 +08:00
最佳实践请参考Torndo源码
mengzhuo
2015-02-09 23:54:51 +08:00
简单的说,没有办法
因为epoll不是银弹,异步仅仅适用于IO密集

工作中碰到CPU密集一般是规避计算、减少内存分配(减少function call、memoryview+zero copy黑科技、更改算法数据结构的、甚至是改通讯协议)

实在没办法避免的话,一般用多进程处理,或者用延后处理库:celery

恰好最近仿照Tornado,写了一个ioloop(你可以看成是Tornado的核心部分)
https://github.com/mengzhuo/ioloop
puncsky
2015-02-10 02:24:52 +08:00
我觉得你的理解是对的,楼上说的对,仅仅适用于IO密集,因为能够解除 thread-per-connection 的关系,变成 event-driven。这叫做 reactor pattern。

如果 event loop 也变成 async 的,那就是 proactor pattern.

http://www.puncsky.com/blog/2015/01/13/understanding-reactor-pattern-for-highly-scalable-i-o-bound-web-server/
est
2015-02-10 08:59:31 +08:00
> 在第39行,如果有个task需要执行1000s,那么这个时候进程就会阻塞在这里,其他客户得不到响应

这得看1000s阻塞的是什么东西,假如这1000s是也在等待其他IO,那么聪明一点的调度器会把纤程拿过来继续下一次epoll。

假如这1000s是把你8个核心跑满的计算小数点后100000000000000000位的Pi,那么神仙都没办法,只能大家一起等了。
veezzz
2015-02-12 10:30:57 +08:00
嗯,之前问过相关的问题,epoll只是IO的多路复用,我的理解是相当于一次性注册多个IO事件,然后让epoll去批量处理,但是epoll等待IO事件的时候会阻塞,不过可以设置让它马上返回,或者在一定时间内,至少有一个事件后返回 /t/159115

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/169651

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX