python tornado开启多进程的几种方法
作者:终成一个大象
以下各种方式仅供参考,本人亲测只有官方提供的方式比较靠谱。
1. 使用多个进程启动多个Tornado实例
import tornado.httpserver import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") if __name__ == "__main__": app = tornado.web.Application([(r"/", MainHandler)]) server = tornado.httpserver.HTTPServer(app) server.bind(8888) server.start(0) # 0 表示启动与CPU数量相同的进程 tornado.ioloop.IOLoop.current().start()
2. 使用tornado.process.fork_processes()方法启动多个进程
import tornado.httpserver import tornado.ioloop import tornado.web import tornado.process class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") if __name__ == "__main__": app = tornado.web.Application([(r"/", MainHandler)]) server = tornado.httpserver.HTTPServer(app) server.bind(8888) tornado.process.fork_processes(2) #
tornado.process.fork_processes(2) 表示启动2个进程,每个进程都会调用 server.start(0) 来启动Tornado实例。注意:在使用 tornado.process.fork_processes() 启动多进程时,需要在 if __name__ == "__main__": 中调用该方法,否则会出现错误。
完整代码如下:
import tornado.httpserver import tornado.ioloop import tornado.web import tornado.process class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") if __name__ == "__main__": app = tornado.web.Application([(r"/", MainHandler)]) server = tornado.httpserver.HTTPServer(app) server.bind(8888) tornado.process.fork_processes(2) server.start(0) tornado.ioloop.IOLoop.current().start()
3.使用标准库中的multiprocessing
除了以上提到的方式,还可以使用Python标准库中的multiprocessing模块来启动多个Tornado进程,具体实现可以参考以下示例代码:
import tornado.httpserver import tornado.ioloop import tornado.web from multiprocessing import Process class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") def start_tornado(): app = tornado.web.Application([(r"/", MainHandler)]) server = tornado.httpserver.HTTPServer(app) server.listen(8888) tornado.ioloop.IOLoop.current().start() if __name__ == "__main__": processes = [] for i in range(2): p = Process(target=start_tornado) p.start() processes.append(p) for p in processes: p.join()
这段代码会启动两个Tornado进程,每个进程都会监听8888端口,并使用单独的进程处理请求。
4.使用第三方模块gevent
还有一个方式是使用第三方模块gevent来实现协程并发,配合Tornado使用可以达到类似多进程的效果,但是只使用一个进程。示例代码如下:
import gevent.monkey gevent.monkey.patch_all() import tornado.httpserver import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") if __name__ == "__main__": app = tornado.web.Application([(r"/", MainHandler)]) server = tornado.httpserver.HTTPServer(app) server.bind(8888) server.start(0) # 0 表示启动与CPU数量相同的进程 tornado.ioloop.IOLoop.current().start()
在上面的代码中,我们引入了gevent.monkey模块,使用patch_all()方法将所有的阻塞式IO替换为非阻塞式IO,然后在启动Tornado时,使用server.start(0)方法启动与CPU数量
5.使用官方提供方式
listen:单进程:
async def main(): server = HTTPServer() server.listen(8888) await asyncio.Event.wait() asyncio.run(main())
在许多情况下,tornado.web.Application.listen可用于避免明确创建HTTPServer的需要。
虽然此示例不会单独创建多个进程,但当thereusereuse_port=True参数传递给listen()时,您可以多次运行程序以创建多进程服务。
add_sockets:多过程:
sockets = bind_sockets(8888) tornado.process.fork_processes(0) async def post_fork_main(): server = HTTPServer() server.add_sockets(sockets) await asyncio.Event().wait() asyncio.run(post_fork_main())
add_sockets接口更复杂,但它可以与tornado.process.fork_processes一起使用,以运行从单父分支的所有工作进程的多进程服务。如果您想以bind_sockets以外的某种方式创建监听套接字,add_sockets也可以在单进程服务器中使用。
请注意,使用此模式时,触及事件循环的任何东西都不能在fork_processes之前运行。
bind/start:简单不建议使用的多进程:
server = HTTPServer() server.bind(8888) server.start(0) # Forks multiple sub-processes IOLoop.current().start()
此模式被弃用,因为它需要自Python 3.10以来被弃用的asyncio模块中的接口。在start方法中创建多个进程的支持将在的未来版本中删除。
此模式就是文中所说的第一种模式,单从官方文档来看,这种方式已经被抛弃,本人在实测中也发现存在问题:无法完全关闭fork的子进程。
6.使用supervisor
使用supervisor等进程管理工具来管理多个Tornado进程,这种方式可以更加方便地监控和管理多个进程,不过需要额外的配置和安装进程管理工具。
到此这篇关于python tornado开启多进程的几种方法的文章就介绍到这了,更多相关python tornado多进程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!