我有一个面向事件的服务器,它已经使用了select.epoll()。在
应该解决异步URL(现在应该解决一个新的获取URL的要求)。在
到目前为止,我一直使用请求库,而且我总是同步使用它,而不是异步的。在
如何将请求库(或不同的urllib)与linuxepoll结合使用?在
请求库文档对此有一个注释,但是只提到了异步框架(没有选择.epoll()):http://docs.python-requests.org/en/master/user/advanced/#blocking-or-non-blocking
我没有结婚选择.epoll(). 到现在为止还有效。如果可行的话,我可以用不同的解决方案。在
背景:更大的问题是“我应该使用吗选择.epoll()或python所拥有的众多异步框架之一?”。但StackOverflow的问题不能太宽泛。这就是为什么这个问题集中在“通过选择.epoll()". 如果你对更大的问题有什么建议,请留言。在
如果您好奇,这个问题是我在业余时间开发的一个小项目所需要的:https://github.com/guettli/ipo(IPO是一个基于PostgreSQL的开源异步作业队列)
上面的要点是正确的,从技术上讲,对于多路复用I/O(如
select()
,epoll()
)的阻塞调用以及BSD/iOS、Windows变体,您无法做到这一点。这些调用允许超时规范,因此您可以通过在短时间间隔内重复轮询,然后将工作从主线程传递给异步处理程序来接近。在这种情况下,读取是在主线程上完成的,多个读取可以表示它们准备好了,而主线程主要用于该任务。在如果问题的规模是小到中,那么没有什么能比
epoll()...read()
甚至select()...read()
强。如果您的问题(读取通道的数量)是在小方面。所以我建议你考虑一下——从主线程上尽可能多地处理请求。在如果您正在寻找一个异步解决方案,那么您最好的选择之一是
grequests
库,以便于使用和提高性能。要获得一个想法,请运行以下客户机-服务器对。请注意,在这里使用tornado是无关的,而且只在服务器端,而您关心的是客户端。在试试这个-性能的差别是白天和黑夜。在
您的解决方案由客户端.py类,它使用
grequests
异步发出get()
请求。在服务器.py
客户端.py
^{pr2}$这是一个真正的异步解决方案,或者说是在CPython/python中最接近的解决方案。没有使用轮询器。在
我们在做武器的时候,总是基于高性能来选择武器情况。所以答案还是太宽泛了。在
但你更大的问题更简单只有一个IO绑定程序适合异步。在
epoll和异步的目的是什么?避免CPU等待IO没什么。CPU等待IO块,IO块是因为没有可读取的数据或没有可写入的空间。在
引入缓冲区来降低系统的功耗打电话。什么时候在流上调用read,实际上是从缓冲区读取
Select或epoll是非阻塞的忙轮询(epoll通过中断底层实现)
这很傻,所以有select和epoll。 每次你从缓冲区读取数据,都有数据在等着你,这是高速IO,那么epoll/select就是你的最佳选择选择。还有当缓冲区总是空的时候,它是一个慢流,IO绑定,异步非常适合这种情况。在
我不太了解异步,对我来说,这只是内部的软中断和大量的回调。在
如何将请求库(或不同的urllib)与linuxepoll结合使用?在
不幸的是,除非在构建这样一个库时考虑到了这种集成,否则您不能这样做。epoll,以及选择/poll/kqueue等都是I/O多路复用系统调用,需要围绕其构建整体程序架构。在
简单地说,一个典型的程序结构可以归结为
在此之后,外部代码的工作就是处理这些描述符,即计算出有多少数据可用,调用一些回调等
如果库使用常规阻塞套接字,则并行化它的唯一方法是使用线程/进程 这里有一个关于这个主题的很好的article,示例使用C,这很好,因为它更容易理解引擎盖下实际发生的事情
异步框架和请求库
让我们看看有什么建议here
请求线程使用线程
grequests-与gevent集成(这是另一个故事,见下文)
请求未来事实上也是线程/进程
它们都与真正的异步性无关
我应该用吗选择.epoll()或python拥有的众多异步框架之一
请注意,epoll是linux特有的beast,它无法工作,即在具有不同机制的OS X上,称为kqueue。当你在写一个通用的工作队列时,这似乎不是一个好的解决方案。在
现在回到python。您可以选择以下选项:
线程/进程/同期期货-不太可能,因为你的应用程序是典型的C10K服务器
epoll/kqueue-你必须自己做所有事情。在获取httpurl的情况下,您不仅需要处理HTTP/ssl,还需要处理异步DNS解析。还可以考虑使用提供一些基本基础设施的asyncore[]
twisted/tornado基于回调的框架,已经为您完成了所有底层工作
gevent-如果您要重用现有的块库(urllib、requests等)并同时使用python2.x和python3.x,那么您可能会喜欢这样的解决方案。对于一个像你这样大小的应用程序,它可能没问题,但我不会把它用于任何更大的,应该是坚如磐石和运行在prod
异步
它有你可能需要的一切。 还有很多库使用流行的RDBMs和http https://github.com/aio-libs
但是它缺乏对python2.x的支持,有ports到python2.x的asyncio,但不确定它们有多稳定
最后
因此,如果我可以牺牲python2.x,我个人会选择asyncio和相关的库
如果您真的需要Python2.x,请根据所需的稳定性和假定的峰值负载使用上述方法之一
相关问题 更多 >
编程相关推荐