运行多个龙卷风进程 [英] run multiple tornado processess

查看:26
本文介绍了运行多个龙卷风进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了有关如何运行 N 个 Tornado 进程的各种文章和教程,其中 N = 内核数.我的代码运行正常,在所有 16 个内核上运行,但不知何故我设法搞砸了,我需要重新审视这一点.

I've read various articles and tutorials on how to run N number of Tornado processes, where N=number of cores. My code was working, running on all 16 cores but I somehow managed to screw it up and I need fresh eyes on this.

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

from core import settings
from core import coreService
import services

from tornado.options import define, options, parse_command_line

define("port", default=settings.SERVER_PORT, help="run on the given port", type=int)



app = tornado.web.Application([
    (r'/upload', coreService.Upload)
])

if __name__ == "__main__":
    tornado.options.parse_command_line()
    server = tornado.httpserver.HTTPServer(app, max_buffer_size=1024*1024*201)
    server.bind(options.port)
    # autodetect cpu cores and fork one process per core
    server.start(0)
    try:        
        print 'running on port %s' % options.port
        tornado.ioloop.IOLoop.instance().start()

    except KeyboardInterrupt:
        tornado.ioloop.IOLoop.instance().stop()

此代码引发此错误:

File "/opt/tornado/tornado/process.py", line 112, in fork_processes
    raise RuntimeError("Cannot run in multiple processes: IOLoop instance "
RuntimeError: Cannot run in multiple processes: IOLoop instance has already been initialized. You cannot call IOLoop.instance() before calling start_processes()

我只是没看到.谢谢

:

正如本所说,我的一种方法给我带来了麻烦.这是该方法的代码,有人可能会从中受益:

As Ben said, one of my methods was giving me trouble. This is the code of that method, someone may benefit from this:

from tornado import gen
import motor

db = motor.MotorClient().open_sync().proba
class Upload(BaseHandler):
    @gen.engine
    def post(self):
        fs = yield motor.Op(motor.MotorGridFS(db).open)

        gridin = yield motor.Op(fs.new_file)
        yield motor.Op(gridin.write, 'First part\n')
        yield motor.Op(gridin.write, 'Second part')
        yield motor.Op(gridin.close)

        print gridin._id
        self.write(str(gridin._id))
        self.finish()

编辑 2

我找到了问题的最终解决方案.正如 Ben 所指出的,上述方法给我带来了麻烦.电机文档中记录了将电机与 Tornado 应用程序结合使用的正确方法.这是一个对我有用的except:

I've found the final solution to my problem. As pointed out by Ben the method above was giving me trouble. The correct way to include Motor with Tornado application is documented on Motor documentation. Here is an except which is working for me:

if __name__ == "__main__":
    tornado.options.parse_command_line()        
    try:
        server = tornado.httpserver.HTTPServer(app, max_buffer_size=1024*1024*201)
        server.bind(8888)
        server.start(0) # autodetect cpu cores and fork one process per core
        db = motor.MotorClient().open_sync().proba
        print 'running on port %s' % options.port
        # Delayed initialization of settings
        app.settings['db'] = db # from this point on db is available as self.settings['db']
        tornado.ioloop.IOLoop.instance().start()

    except KeyboardInterrupt:
        tornado.ioloop.IOLoop.instance().stop()

推荐答案

如果我注释掉核心"和服务"导入,它会按预期工作.这些模块之一中的某些内容必须初始化单例事件循环(可能是间接的,例如通过创建全局 AsyncHTTPClient 实例).此警告是为了保护您免受在父进程中创建的这些对象在子进程中不起作用的事实.您必须找到创建这些对象的位置(遗憾的是没有很好的工具)并在 fork 之后移动它们,以便在子进程中创建它们.

It works as expected if I comment out the "core" and "services" imports. Something in one of those modules must be initializing the singleton event loop (perhaps indirectly, e.g. by creating a global AsyncHTTPClient instance). This warning is protecting you from the fact that these objects that were created in the parent process won't work in the child. You'll have to find the places where these objects are being created (unfortunately there aren't good tools for this) and move them after the fork so they are created in the child processes instead.

这篇关于运行多个龙卷风进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆