我有一个多处理龙卷风Web服务器,我想创建另一个在后台执行某些操作的进程。
我的服务器包含以下代码
start_background_process
app = Application([<someurls>])
server = HTTPServer(app)
server.bind(8888)
server.start(4) # Forks multiple sub-processes
IOLoop.current().start()
def start_background_process():
process = multiprocessing.Process(target=somefunc)
process.start()
一切都很好。
但是当我尝试关闭服务器时(通过crtl c或发送信号)
我得到AssertionError: can only join a child process
我理解了这个问题的原因: 当我使用多进程创建进程时,调用进程连接方法 在“atexit”中注册并且因为龙卷风做了一个简单的fork所有它的孩子也调用我创建的进程的join方法而且不能,因为进程是他们的兄弟而不是他们的儿子? 那么如何在龙卷风中正常打开一个过程?
答案 0 :(得分:3)
“ HTTPTserver start ”使用 os.fork 来分叉4个子进程,因为它可以在source code中看到。
如果您希望所有4个子进程都执行您的方法,则必须在分叉进程后调用它。
考虑到这一点,您的代码可以更改为如下所示:
import multiprocessing
import tornado.web
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
# A simple external handler as an example for completion
from handlers.index import IndexHandler
def method_on_sub_process():
print("Executing in sub-process")
def start_background_process():
process = multiprocessing.Process(target=method_on_sub_process)
process.start()
def main():
app = tornado.web.Application([(r"/", IndexHandler)])
server = HTTPServer(app)
server.bind(8888)
server.start(4)
start_background_process()
IOLoop.current().start()
if __name__ == "__main__":
main()
此外,为了在任何键盘中断期间保持程序的行为清洁,请通过 try ... except 子句围绕服务器实例化,如下所示:
def main():
try:
app = tornado.web.Application([(r"/", IndexHandler)])
server = HTTPServer(app)
server.bind(8888)
server.start(4)
start_background_process()
IOLoop.current().start()
except KeyboardInterrupt:
IOLoop.instance().stop()