最近在忙项目的同时,也想把自己的小工具用自己的index.py重写一下。为了从实践中完善index.py。
但在尝试使用docker运行index.py的时候,出了问题。
问题
众所周知,docker容器在正常终止时会向主进程(pid 1)发送一个SIGTERM信号。一般来说,程序是能正常接收这个信号,并且退出的。
但……在index.py中偏偏不行!
原因
众所周知,Python的os.system
调用的是C函数system
。
它的执行过程可以用三个词概括:fork、exec、wait。
这里会出现一个问题,它不仅会阻塞调用它的程序,并且在所执行的程序执行完成之前,在Python里处理信号的程序将不会被调用。
解决
于是,如何解决,清晰明了。使用下述函数代替代码里的每一处 os.system
即可。
import os
import time
import signal
import subprocess
def exec(*commands):
process = subprocess.Popen(" ".join(commands), cwd=os.getcwd(), shell=True)
def sigterm_handler(signo, frame):
process.terminate()
process.wait()
signal.signal(signal.SIGTERM, sigterm_handler)
while process.poll() is None:
time.sleep(1)
return process.returncode
反思
不要滥用os.system
,尽量以subprocess
代替。
Python官方诚不欺我。😭