简体   繁体   English

Python如何使用扭曲的多线程/异步HTTP服务器

[英]Python how can I do a multithreading/asynchronous HTTP server with twisted

Now I wrote ferver by this tutorial: https://twistedmatrix.com/documents/14.0.0/web/howto/web-in-60/asynchronous-deferred.html But it seems to be good only for delayng process, not actually concurently process 2 or more requests. 现在,我通过本教程编写了ferver: https ://twistedmatrix.com/documents/14.0.0/web/howto/web-in-60/asynchronous-deferred.html但这似乎仅对延迟过程有好处,实际上并没有同时处理2个或更多请求。 My full code is: 我的完整代码是:

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()

But when I passing 2 requests console output is like: 但是当我传递2个请求时,控制台输出如下:

Sleeping 睡眠

Sorry to keep you waiting. 对不起,让你久等了。

Sleeping 睡眠

Sorry to keep you waiting. 对不起,让你久等了。

But if it was concurrent it should be like: 但是,如果是并发的,则应为:

Sleeping 睡眠

Sleeping 睡眠

Sorry to keep you waiting. 对不起,让你久等了。

Sorry to keep you waiting. 对不起,让你久等了。

So the question is how to make twisted not to wait until response is finished before processing next? 那么问题是如何使扭曲不等到响应完成之后再进行下一步处理? Also make_delay IRL is a large function with heavi logic. 同样, make_delay IRL是具有重逻辑的大型函数。 Basically I spawn lot of threads and make requests to other urls and collecting results intro response, so it can take some time and not easly to be ported 基本上,我会产生大量线程并向其他url发出请求并收集结果介绍响应,因此可能要花一些时间,而且移植起来并不容易

Twisted processes everything in one event loop. Twisted在一个事件循环中处理所有内容。 If somethings blocks the execution, it also blocks Twisted. 如果某些东西阻止了执行,它也会阻止Twisted。 So you have to prevent blocking calls. 因此,您必须防止阻塞呼叫。

In your case you have time.sleep(5) . 在您的情况下,您有time.sleep(5) It is blocking. 它正在阻塞。 You found the better way to do it in Twisted already: deferLater() . 您已经在Twisted中找到了更好的方法: deferLater() It returns a Deferred that will continue execution after the given time and release the events loop so other things can be done meanwhile. 它返回一个Deferred ,它将在给定时间后继续执行并释放事件循环,以便可以同时执行其他操作。 In general all things that return a deferred are good. 通常,所有返回延迟的事物都是好的。

If you have to do heavy work that for some reason can not be deferred, you should use deferToThread() to execute this work in a thread. 如果必须执行繁重的工作而由于某些原因而无法推迟,则应使用deferToThread()在线程中执行此工作。 See https://twistedmatrix.com/documents/15.5.0/core/howto/threading.html for details. 有关详细信息,请参见https://twistedmatrix.com/documents/15.5.0/core/howto/threading.html

You can use greenlents in your code (like threads). 您可以在代码中使用greenlents(例如线程)。

You need to install the geventreactor - https://gist.github.com/yann2192/3394661 您需要安装geventreactor- https: //gist.github.com/yann2192/3394661

And use reactor.deferToGreenlet() 并使用reactor.deferToGreenlet()

Also

In your long-calculation code need to call gevent.sleep() for change context to another greenlet. 在长时间计算的代码中,需要调用gevent.sleep()来将上下文更改为另一个greenlet。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM