我在python3中使用服务器机器人(使用asyncio),我想为协作者添加更新功能,以便立即测试他们的贡献。它托管在我通过ssh访问的VPS上。我在tmux中运行该进程,其他贡献者通常很难在他们进行提交后重新启动脚本等等。我对python很新,我只是使用我能找到的东西。到目前为止,我已经使用subprocess.Popen来运行git pull,但我无法自动重启脚本。
有没有办法终止正在运行的asyncio循环(理想情况下没有错误)并重新启动它?
谢谢!
答案 0 :(得分:0)
您无法启动event_loop.stop()所停止的事件循环 并且为了合并更改,您必须重新启动脚本(在您拥有的对象上可能不存在某些方法等)
我会推荐类似的东西:
asyncio.ensure_future(git_tracker)
async def git_tracker():
# check for changes in version control, maybe wait for a sync point and then:
sys.exit(0)
这引发了SystemExit,但尽管这样可以干净地退出程序。
在python $file.py
和while true; do git pull && python $file.py ; done
这是(据我所知)解决问题的最简单方法。
答案 1 :(得分:0)
对于您的用例,为了保持安全,您可能需要终止该过程并重新启动它。
答案 2 :(得分:0)
作为一个死灵法师,我想我提供了一个我们在UNIX系统中使用的最新解决方案。
使用os.execl函数,您可以告诉python用新的替换当前进程:
这些函数都执行一个新程序,以替换当前进程;他们不回来。在Unix上,新的可执行文件已加载到当前进程中,并且将具有与调用方相同的进程ID。错误将报告为OSError异常。
在我们的例子中,我们有一个执行killall python3.7
的bash脚本,将SIGTERM信号发送到我们的python应用程序,然后通过signal模块监听它并正常关闭:
loop = asyncio.get_event_loop()
loop.call_soon_threadsafe(loop.stop)
sys.exit(0)
该脚本将在后台启动应用程序并完成。
请注意,
killall python3.7
将向每个python3.7进程发送SIGTERM
信号!
当我们需要重新启动时,请使用以下命令:
os.execl("./restart.sh", 'restart.sh')
第一个参数是文件的路径,第二个参数是进程的名称。