背景
我有一个名为server.py
的Python 3脚本,它使用了内置的http.server
模块。该脚本可以归纳如下:
from http.server import HTTPServer
from http.server import BaseHTTPRequestHandler
class MyRequestHandler (BaseHTTPRequestHandler):
def do_POST(self):
# Code omitted for brevity
def do_GET(self):
# Code omitted for brevity
def start_server():
# Begin serving
# -------------
server = HTTPServer(('', port), MyRequestHandler)
print("server now running on port {0} ...".format(port))
server.serve_forever()
# Start the Server
# ----------------
if __name__ == '__main__':
start_server()
MyRequestHandler
可以根据请求的URI动态导入模块来处理GET和POST请求。
虽然以上方法可行,但是在那个脚本创建之后,有一个需求需要远程更新整个“包”(即服务器脚本加上所有加载“on-the-fly”的“模块脚本”,并且它们位于子文件夹中)。
为此,我编写了另一个Python 3服务器脚本(称为updater.py
),当接到指令时会获取一个zip文件,然后解压缩以覆盖原始的server.py
脚本以及所有其他相关脚本和子文件夹。
问题
这一切都很顺利,但是现在我遇到了麻烦。我认为最好的方法是让updater.py
脚本控制server.py
的运行。它可以关闭server.py
和与其相关的一切,在覆盖所有内容之前,然后在覆盖后重新启动。
基于这个想法,我已经使用subprocess.Popen
开启了服务器进程,相信我可以在覆盖server.py
之前杀死Python进程,但是这并没有像希望的那样工作。下面是我编写的trial.py
脚本以测试这个想法:
import sys
import subprocess
def main():
def start_process():
proc = subprocess.Popen([sys.executable, 'server.py'])
print("Started process:")
print(proc.pid)
return proc
def kill_process(the_process):
print("Killing process:")
print(the_process.pid)
the_process.kill()
process = None
while True:
user_input = input("Type something: ")
if user_input == 'start':
process = start_process()
if user_input == 'kill':
kill_process(process)
if user_input == 'exit':
break
if __name__ == '__main__':
main()
这似乎启动并终止了一个Python进程,但是当此脚本运行时,服务器并未运行,因此我不确定它正在启动和终止什么!输入“start”,然后输入“exit”(从而退出
trial.py
脚本)允许服务器运行,尽管我不明白为什么,因为我认为subprocess.Popen
应该使生成的进程独立于父进程运行?编辑:感谢@Håken Lid的敏锐观察,我注意到我所做的一切都只是跳出了
while
循环,而没有退出脚本。这使我相信while
循环以某种方式阻止子进程运行(因为一旦退出循环,服务器就会启动)。