设想
我有一个 rpc 服务器,它需要生成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 的套接字
退出主进程似乎不会帮助或影响套接字问题的关闭。因此,为了说明服务器重新启动的问题,模拟了在第一个服务器关闭后启动具有相同参数的第二个服务器。
以下工作完美:
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()
但是,如果创建了一个工人,它会提出一个socket.error
说法,即套接字已在使用中:
s = SimpleXMLRPCServer.SimpleXMLRPCServer((HOST, PORT))
worker = multiprocessing.Process(target=_job, args=(None,))
worker.start()
s.server_close()
s = SimpleXMLRPCServer.SimpleXMLRPCServer((HOST, PORT)) #raises socket.error
worker.join()
s.server_close()
手动关闭服务器套接字确实有效:
import socket
s = SimpleXMLRPCServer.SimpleXMLRPCServer((HOST, PORT))
worker = multiprocessing.Process(target=_job, args=(None,))
worker.start()
s.socket.shutdown(socket.SHUT_RDWR)
s = SimpleXMLRPCServer.SimpleXMLRPCServer((HOST, PORT))
worker.join()
s.server_close()
但这种行为真的让我很担心。我没有以任何方式将套接字传递给工人,但它似乎无论如何都得到了它。
之前发布过类似的问题,但它们倾向于将套接字传递给工作人员,此处不打算这样做。如果我通过发送套接字,我可以在工作人员中关闭它并绕过shutdown
黑客:
def _job2(notMySocket):
notMySocket.close()
for _ in range(3):
print multiprocessing.current_process(), "is working"
time.sleep(2)
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()
但是服务器的socket绝对没有理由去访问worker。我有点不喜欢这个解决方案,即使它是迄今为止最好的解决方案。
问题
有没有办法限制使用时分叉的内容,multiprocessing.Process
以便只复制我想传递给目标的内容,而不是所有打开的套接字和其他内容?
就我而言,要使此代码正常工作:
s = SimpleXMLRPCServer.SimpleXMLRPCServer((HOST, PORT))
childPipe, parentPipe = multiprocessing.Pipe()
worker = multiprocessing.Process(target=_job, args=(childPipe,))
worker.start()
s.server_close()
s = SimpleXMLRPCServer.SimpleXMLRPCServer((HOST, PORT)) #raises socket.error
worker.join()
s.server_close()