基于 poll 的服务器程序如何实现请求超时

2016-06-17 11:23:39 +08:00
 feng32

如果源请求是通过 pollin 获取的,然后把请求丢到一个线程池去处理,在每个线程内部处理超时,这个是比较容易实现的


现在的场景是,源请求是通过 pollin 获取的,服务器同时还维护一个 socket 池,因此总共需要 poll N + 1 个 socket ;对于每一个源请求,需要检查这个 socket 池中的对应项有没有 pollin 事件:

在这种模式下,万一有个源请求等了一个小时也没有应答也是有可能的,所以最好设置一个超时


但是 poll 是 I/O 事件驱动的,超时不是一种事件,所以感觉要实现的话比较别扭,我能想到的一个方法是这样的:

还想到一个方法是这样的:

感觉这两种方法都不是特别理想,请问这类问题通常的解法是什么?

2651 次点击
所在节点    程序员
5 条回复
fcicq
2016-06-17 11:51:13 +08:00
你想到的第一个解法换成优化的数据结构就可以了. timer wheel
sen506
2016-06-17 11:53:30 +08:00
维护一个超时事件堆 socket 入池同时加入超时事件, pollin 触发后重新更新触发事件的 socket 的超时时间, 每次从堆中取出一个超时时间,每次 poll 的超时时间为从堆中取出的那个时间
sen506
2016-06-17 12:11:46 +08:00
补充下,每次 poll 事件触发后,检查下堆顶,就可以知道是否有 socket 超时了,
ryd994
2016-06-17 12:47:23 +08:00
维护一个超时堆,按超时时间排序,这样每次遍历只要按顺序查询,不需要扫全表。
k9982874
2016-06-17 14:40:21 +08:00
记一个动作时间,在你的主循环里检查一下是否超时就行。

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

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

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

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

© 2021 V2EX