背景
我有一个名为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通过“动态”导入模块来处理GET和POST请求,具体取决于用于请求的URI.
以上工作正常,但是,在创建该脚本之后,需要能够远程更新脚本的整个“包”(即服务器脚本,以及加载的所有“模块脚本”) “即时”并位于子文件夹中).
为此,我在Python 3中编写了另一个服务器脚本(称为updater.py),当被指示时,它将检索一个zip文件,然后解压缩以覆盖原始server.py脚本以及所有其他相关脚本和子-folders.
题
这一切都很好,但我现在已经碰壁了.我想,最好的方法是让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”然后“退出”(从而退出trial.py脚本)允许服务器运行,虽然我无法理解为什么,因为我认为subprocess.Popen应该导致生成的进程独立于父进程运行处理?
编辑:感谢@HåkenLid在下面的敏锐观察,我注意到我所做的就是打破while循环,而不是退出脚本.这让我相信while循环以某种方式阻止子进程运行(因为一旦退出循环,服务器就会启动).
最佳答案 根据我们的讨论,我建议使用某种方法从“server.py”清空stdio缓冲区.如果您还希望能够提供用户输入,则在等待主线程上的用户输入时,您将需要一个线程来执行打印(或者只是将缓冲区清空到黑洞中).这是我如何做到这一点的粗略想法..
import sys
import subprocess
from threading import Thread
#This could probably be solved with async, but I still
#haven't learned async as well as I know threads
def main():
def start_process():
proc = subprocess.Popen([sys.executable, 'server.py'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
print("Started process:")
def buf_readerd(proc, inbuf, outbuf):
while proc.poll() is None:
outbuf.write(inbuf.readline()) #may need to add a newline.. I'm not sure if readline ends in a \n
stdoutd = Thread(target=buf_readerd, args=(proc, proc.stdout, sys.stdout), daemon=True)
stderrd = Thread(target=buf_readerd, args=(proc, proc.stderr, sys.stderr), daemon=True)
stdoutd.start()
stderrd.start()
print("started pipe reader daemons")
print(proc.pid)
return proc
# ...