Python如何使用twisted进行多线程/异步HTTP服务器

时间:2015-12-03 12:23:44

标签: python multithreading http server twisted

现在我通过本教程编写了ferver: https://twistedmatrix.com/documents/14.0.0/web/howto/web-in-60/asynchronous-deferred.html 但它似乎只适用于延迟进程,而不是实际上处理2个或更多请求。我的完整代码是:

from twisted.internet.task import deferLater
from twisted.web.resource import Resource
from twisted.web.server import Site, NOT_DONE_YET
from twisted.internet import reactor, threads
from time import sleep


class DelayedResource(Resource):
    def _delayedRender(self, request):
        print 'Sorry to keep you waiting.'
        request.write("<html><body>Sorry to keep you waiting.</body></html>")
        request.finish()

    def make_delay(self, request):
        print 'Sleeping'
        sleep(5)
        return request


    def render_GET(self, request):
        d = threads.deferToThread(self.make_delay, request)
        d.addCallback(self._delayedRender)
        return NOT_DONE_YET

def main():
    root = Resource()
    root.putChild("social", DelayedResource())
    factory = Site(root)
    reactor.listenTCP(8880, factory)
    print 'started httpserver...'
    reactor.run()


if __name__ == '__main__':
    main()

但是当我传递2个请求时,控制台输出就像:

睡眠

很抱歉让你久等。

睡眠

很抱歉让你久等。

但如果它是并发的,它应该是:

睡眠

睡眠

很抱歉让你久等。

很抱歉让你久等。

所以问题是如何使扭曲不要等到响应完成然后再处理? 同样make_delay IRL是一个具有重逻辑的大功能。基本上我产生了很多线程并向其他网址发出请求并收集结果介绍响应,所以它可能需要一些时间而且不容易被移植

2 个答案:

答案 0 :(得分:0)

Twisted在一个事件循环中处理所有内容。如果某些事情阻止执行,它也会阻止扭曲。所以你必须阻止阻止呼叫。

在您的情况下,您有time.sleep(5)。它是封锁的。您已经在Twisted中找到了更好的方法:deferLater()。它返回一个Deferred,它将在给定时间后继续执行并释放事件循环,以便同时完成其他任务。一般来说,所有返回延迟的东西都是好的。

如果由于某种原因无法推迟繁重工作,则应使用deferToThread()在线程中执行此工作。有关详细信息,请参阅https://twistedmatrix.com/documents/15.5.0/core/howto/threading.html

答案 1 :(得分:0)

您可以在代码中使用greenlents(如线程)。

您需要安装geventreactor - https://gist.github.com/yann2192/3394661

并使用reactor.deferToGreenlet()

另外

在你的长计算代码中,需要调用gevent.sleep()来将更改上下文调用到另一个greenlet。

msecs = 5 * 1000
timeout = 100
for xrange(0, msecs, timeout):
    sleep(timeout)
    gevent.sleep()