Tornado Multiprocessing & Asynchronous

Basic version:

#coding=utf-8

import tornado.web
import tornado.httpserver
import tornado.options
import tornado.ioloop

from tornado.options import options , define
define("port",default=8001,help="跑在8001",type=int)

import time
class SleepHandler(tornado.web.RequestHandler):
    def get(self):
        time.sleep(5)
        self.write("this is SleepHandler...")

class DirectHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("this is DirectHandler...")

if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(
        handlers = [
            (r"/d",DirectHandler),
            (r"/s",SleepHandler),
        ],
        debug = True
    )
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

multi-process version

Note that the debug function must be turned off! ! ! Otherwise: Cannot run in multiple processes: IOLoop instance

#coding:utf-8

import tornado.web
import tornado.httpserver
import tornado.options
import tornado.ioloop

from tornado.options import options , define
define("port",default=8001,help="跑在8001",type=int)

import time
class SleepHandler(tornado.web.RequestHandler):
    def get(self):
        time.sleep(10)
        self.write("this is SleepHandler...")

class DirectHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("this is DirectHandler...")

if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(
        handlers = [
            (r"/d",DirectHandler),
            (r"/s",SleepHandler),
        ],
        debug = False
    )
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.bind(options.port)
    http_server.start(0)
    # [I 150610 10:42:05 process:115] Starting 4 processes
    tornado.ioloop.IOLoop.instance().start()

bind documentation translation

def bind(self, port, address=None, family=socket.AF_UNSPEC, backlog=128):
    """
    绑定server到指定地址的端口上。
    调用start来启动server。如果想把这个server跑在单线程上,可以调用listen方法,listen是bind和start方法的单进程模式的“快捷键”。
    地址可能是ip地址或者hostname。如果是hostname,server将监听其所有关联ip。
    地址若是空字符串将监听不到任何可用接口。family参数可设置为socket.AF_INET或socket.AF_INET6来约定ipv4或者是ipv6地址,缺省情况下会启用所有可用的。
    backlog参数与socket.listen同义。
    bind方法会多次在start方法前调用来监听多个端口或者接口。
    """
    sockets = bind_sockets(port, address=address, family=family,
                           backlog=backlog)
    if self._started:
        self.add_sockets(sockets)
    else:
        self._pending_sockets.extend(sockets)

start document translation

def start(self, num_processes=1):
    """
    默认情况下,但进程运行server,不会fork任何额外的子进程。
    如果num_processes为None或<=0 ,会根据机器的cpu核数fork子进程。若num_processes>=1,就fork这个数目的子进程。
    因为我们使用的是进程而不是线程,所以不会在server code之间共享内存。

    特别注意,多进程与自动装载模型不兼容。在调用TCPServer.start(n)前,任何IOLoop都不能创建和引用。
    """
    assert not self._started
    self._started = True
    if num_processes != 1:
        process.fork_processes(num_processes)
    sockets = self._pending_sockets
    self._pending_sockets = []
    self.add_sockets(sockets)

Asynchronous version 1

#coding:utf-8

import tornado.web
import tornado.httpserver
import tornado.options
import tornado.ioloop

from tornado.options import options , define
define("port",default=8001,help="跑在8001",type=int)

import time
class SleepHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self):
        tornado.ioloop.IOLoop.instance().add_timeout(time.time() + 5, callback=self.on_response)

    def on_response(self):
        self.write("this is SleepHandler...")
        self.finish()


class DirectHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("this is DirectHandler...")

if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(
        handlers = [
            (r"/d",DirectHandler),
            (r"/s",SleepHandler),
        ],
        debug = False
    )
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.bind(options.port)
    http_server.start(1)
    tornado.ioloop.IOLoop.instance().start()

Modify the code of sleep.py as above, that is, add the decorator @tornado.web.asynchronous in front of the get() method. Its function is to change the default _auto_fininsh value of the tornado server itself to false. If this decorator is not used, after the client accesses the server's get() method and gets the return value, the connection between the two will be disconnected, but after @tornado.web.asynchronous is used, the connection will not be closed until The connection is closed after self.finish() is executed.

tornado.ioloop.IOLoop.instance().add_timeout() is also a function that implements asynchronous. time.time()+17 provides a parameter to the previous function, which realizes the function equivalent to time.sleep(17), but , has not been completed, when this operation is completed, execute self.render("sleep.html") in the callback function on_response(), and close the connection self.finish(). 
https://github.com/qiwsir/StarterLearningPython/blob/master/309.md

Asynchronous version two

#coding:utf-8

import tornado.web
import tornado.httpserver
import tornado.options
import tornado.ioloop
import tornado.gen

from tornado.options import options , define
define("port",default=8001,help="跑在8001",type=int)

import time
class SleepHandler(tornado.web.RequestHandler):
    @tornado.gen.coroutine
    def get(self):
        #使用yield得到了一个生成器,先把流程挂起,等完全完毕,再唤醒继续执行。另,生成器都是异步的。
        yield tornado.gen.Task(tornado.ioloop.IOLoop.instance().add_timeout, time.time() + 5)
        self.write("this is SleepHandler...")


class DirectHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("this is DirectHandler...")

if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(
        handlers = [
            (r"/d",DirectHandler),
            (r"/s",SleepHandler),
        ],
        debug = False
    )
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.bind(options.port)
    http_server.start(1)
    tornado.ioloop.IOLoop.instance().start()

转自:https://blog.csdn.net/yongche_shi/article/details/53694145

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325255037&siteId=291194637