python – 拥有子进程允许rpc-server在子进程存活时重新启动
脚本
我有一个rpc-server需要产生持续数天的重要进程(multiprocessing.Process).出于安全/安全的原因,我不希望这些进程生存依赖于rpc-server.因此,我希望服务器能够在流程运行时能够重启并能够重启. 孤儿进程 这个问题是可以解决的(不要粘贴它你不想放弃以前的工作,它将关闭你的python会话): import os import multiprocessing import time def _job(data): for _ in range(3): print multiprocessing.current_process(),"is working" time.sleep(2) print multiprocessing.current_process(),"is done" #My real worker gets a Connection-object as part of a #multiprocessing.Pipe among other arguments worker = multiprocessing.Process(target=_job,args=(None,)) worker.daemon = True worker.start() os._exit(0) 问题:如果worker工作,则关闭rpc-server的套接字 退出主进程似乎没有帮助或影响socket问题的关闭.因此,为了说明服务器重新启动的问题,在第一个服务器关闭后启动第二个具有相同参数的服务器进行模拟. 以下工作完美: import SimpleXMLRPCServer HOST = "127.0.0.1" PORT = 45212 s = SimpleXMLRPCServer.SimpleXMLRPCServer((HOST,PORT)) s.server_close() s = SimpleXMLRPCServer.SimpleXMLRPCServer((HOST,PORT)) s.server_close() 但是,如果创建了一个worker,它会引发一个socket.error,说套接字已被使用: s = SimpleXMLRPCServer.SimpleXMLRPCServer((HOST,PORT)) worker = multiprocessing.Process(target=_job,)) worker.start() s.server_close() s = SimpleXMLRPCServer.SimpleXMLRPCServer((HOST,PORT)) #raises socket.error worker.join() s.server_close() 手动关闭服务器套接字确实有效: import socket s = SimpleXMLRPCServer.SimpleXMLRPCServer((HOST,)) worker.start() s.socket.shutdown(socket.SHUT_RDWR) s = SimpleXMLRPCServer.SimpleXMLRPCServer((HOST,PORT)) worker.join() s.server_close() 但这种行为真让我担心.我没有以任何方式将套接字传递给worker,但无论如何它似乎都得到了它. 之前发布过类似的问题,但是它们倾向于将套接字传递给工作者,而这里并不打算这样做.如果我发送套接字,我可以在工作中关闭它并绕过关闭hack: def _job2(notMySocket): notMySocket.close() for _ in range(3): print multiprocessing.current_process(),"is done" s = SimpleXMLRPCServer.SimpleXMLRPCServer((HOST,PORT)) worker = multiprocessing.Process(target=_job2,args=(s.socket,)) worker.start() time.sleep(0.1) #Just to be sure worker gets to close socket in time s.server_close() s = SimpleXMLRPCServer.SimpleXMLRPCServer((HOST,PORT)) worker.join() s.server_close() 但服务器的套接字绝对没有理由访问该工作者.我不喜欢这个解决方案,即使它是迄今为止最好的解决方案. 题 有没有办法限制使用多处理时分叉的内容.过程只有我想要传递给目标的东西才被复制,而不是所有打开的套接字和其他内容? 在我的情况下,要使此代码工作: s = SimpleXMLRPCServer.SimpleXMLRPCServer((HOST,PORT)) childPipe,parentPipe = multiprocessing.Pipe() worker = multiprocessing.Process(target=_job,args=(childPipe,PORT)) #raises socket.error worker.join() s.server_close() 解决方法
如果您使用的是Python 2.x,我认为没有办法在Posix平台上避免这种继承. os.fork将始终用于创建新进程,这意味着父进程的整个状态将被复制到子进程.您所能做的就是立即关闭孩子的插座,这就是您已经在做的事情.避免这种继承的唯一方法是在启动服务器之前启动进程.您可以通过提前启动Process然后使用multiprocessing.Queue来传递工作项(而不是args关键字参数)或multiprocessing.Event来指示它应该实际开始工作.根据您需要发送给子进程的内容,您的用例实际上可能会或可能不会实现.
但是,如果您使用的是Python 3.4(或者可以迁移到3.4),则可以使用
例: def _job2(): for _ in range(3): print multiprocessing.current_process(),"is done" ctx = multiprocessing.get_context('forkserver') worker = ctx.Process(target=_job2) worker.start() (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |