当前位置:网站首页>tornado之多进程服务
tornado之多进程服务
2022-07-26 08:55:00 【还是转转】
tornado多进程开启
在前文"tornado之hello world"中简单介绍过tornado的基本使用。tornado默认启动的是单进程,启动方式如下:
if __name__ == "__main__":
application = tornado.web.Application([(r"/", MainHandler)])
# application.listen(8888)
server = HTTPServer(application)
server.listen(8888)
tornado.ioloop.IOLoop.instance().start()
如果要开启多进程,可进行如下修改:
if __name__ == "__main__":
application = tornado.web.Application([(r"/", MainHandler)])
server = HTTPServer(application)
server.bind(8888)
server.start(2)
tornado.ioloop.IOLoop.instance().start()
启动后生成了3个进程(注意关闭debug模式)。start函数中参数说明如下:
If num_processes is ``None`` or <= 0, we detect the number of cores
available on this machine and fork that number of child
processes. If num_processes is given and > 1, we fork that
specific number of sub-processes.
意思是,当参数小于等于0时,则根据当前机器的cpu核数来创建子进程,大于1时直接根据指定参数创建子进程。
看一下bind函数的说明:
def bind(self, port, address=None, family=socket.AF_UNSPEC, backlog=128,
reuse_port=False):
"""Binds this server to the given port on the given address.
To start the server, call `start`. If you want to run this server
in a single process, you can call `listen` as a shortcut to the
sequence of `bind` and `start` calls.
Address may be either an IP address or hostname. If it's a hostname,
the server will listen on all IP addresses associated with the
name. Address may be an empty string or None to listen on all
available interfaces. Family may be set to either `socket.AF_INET`
or `socket.AF_INET6` to restrict to IPv4 or IPv6 addresses, otherwise
both will be used if available.
The ``backlog`` argument has the same meaning as for
`socket.listen <socket.socket.listen>`. The ``reuse_port`` argument
has the same meaning as for `.bind_sockets`.
This method may be called multiple times prior to `start` to listen
on multiple ports or interfaces.
.. versionchanged:: 4.4
Added the ``reuse_port`` argument.
"""
也就是说,当start函数的参数为1时,listen函数可以代替bind和start。
多进程开启原理
对启动代码进行分析:
先创建一个HTTPServer实例。然后在bind函数中,调用了bind_sockets方法来创建sockets。接着在start方法中,调用process.fork_processes(num_processes)方法来创建子进程,并将sockets通过add_sockets方法添加到server实例中。
也就是说,这一段代码的实质如下:
if __name__ == "__main__":
application = tornado.web.Application([(r"/", MainHandler)])
sockets = tornado.netutil.bind_sockets(8888)
tornado.process.fork_processes(2)
server = HTTPServer(application)
server.add_sockets(sockets)
tornado.ioloop.IOLoop.instance().start()
继续分析fork_process函数,其主要过程如下:
def start_child(i):
pid = os.fork()
if pid == 0:
# child process
_reseed_random()
global _task_id
_task_id = i
return i
else:
children[pid] = i
return None
for i in range(num_processes):
id = start_child(i)
if id is not None:
return id
num_restarts = 0
while children:
try:
pid, status = os.wait()
except OSError as e:
if errno_from_exception(e) == errno.EINTR:
continue
raise
if pid not in children:
continue
id = children.pop(pid)
if os.WIFSIGNALED(status):
gen_log.warning("child %d (pid %d) killed by signal %d, restarting",
id, pid, os.WTERMSIG(status))
elif os.WEXITSTATUS(status) != 0:
gen_log.warning("child %d (pid %d) exited with status %d, restarting",
id, pid, os.WEXITSTATUS(status))
else:
gen_log.info("child %d (pid %d) exited normally", id, pid)
continue
num_restarts += 1
if num_restarts > max_restarts:
raise RuntimeError("Too many child restarts, giving up")
new_id = start_child(id)
if new_id is not None:
return new_id
# All child processes exited cleanly, so exit the master process
# instead of just returning to right after the call to
# fork_processes (which will probably just start up another IOLoop
# unless the caller checks the return value).
sys.exit(0)
从这个源码可以看出,子进程的开启实际上是调用的linux系统提供的fork功能。当子进程存在时,父进程通过一个while循环来处理子进程的终止信号,尝试重启已经停止的子进程,直到超过默认的最大重启次数100。
边栏推荐
- 数据库操作 题目二
- Day06 homework - skill question 7
- P3743 Kotori's equipment
- tcp 解决short write问题
- unity TopDown角色移动控制
- C Entry series (31) -- operator overloading
- [recommended collection] MySQL 30000 word essence summary index (II) [easy to understand]
- CSDN TOP1“一个处女座的程序猿“如何通过写作成为百万粉丝博主?
- Media at home and abroad publicize that we should strictly grasp the content
- Pop up window in Win 11 opens with a new tab ---firefox
猜你喜欢

The idea shortcut key ALT realizes the whole column operation

海内外媒体宣发自媒体发稿要严格把握内容关

Database operation skills 7

Node-v download and application, ES6 module import and export

Kotlin属性与字段

node-v下载与应用、ES6模块导入与导出

JDBC database connection pool (Druid Technology)

Kotlin properties and fields

十大蓝筹NFT近半年数据横向对比

Regular expression: judge whether it conforms to USD format
随机推荐
Mutual transformation of array structure and tree structure
Typescript encryption tool passwordencoder
Learning notes of automatic control principle --- linear discrete system
数据库操作 技能6
Arbitrum Nova release! Create a low-cost and high-speed dedicated chain in the game social field
The idea shortcut key ALT realizes the whole column operation
JDBC database connection pool (Druid Technology)
My meeting of OA project (query)
[eslint] Failed to load parser ‘@typescript-eslint/parser‘ declared in ‘package. json » eslint-confi
合工大苍穹战队视觉组培训Day6——传统视觉,图像处理
基于序的评价指标 (特别针对推荐系统和多标签学习)
209. Subarray with the smallest length
220. Presence of repeating element III
海内外媒体宣发自媒体发稿要严格把握内容关
187. Repeated DNA sequence
Cadence(十)走线技巧与注意事项
zsh: command not found: nvm
day06 作业---技能题7
网络安全漫山遍野的高大上名词之后的攻防策略本质
Kotlin属性与字段