我有一个python脚本,它创建多进程进程,每个进程工作人员都使用subprocess.Popen使用linux数据库实用程序运行一些数据库操作。有时,数据库实用程序会发送SIGTERM。如何处理来自linux命令的SIGTERM,而不终止整个进程树以及当前的进程工作器?
到目前为止,我的代码:
import multiprocessing as mp
import subprocess
import shlex
import signal
class SigTermError(Exception):
pass
def sig_handler(sig, frame):
raise SigTermError( ("Received Signal:{} "
"on line:{} in file:{}")
.format(str(sig)
, str(frame.f_lineno)
, frame.f_code.co_filename))
def do_something_to_hanlde_sigterm():
print('Handled SIGTERM')
def move_on():
print('Moving on')
def run_shell_command(cmd_string):
""" Run a shell command"""
original_sigterm_handler = signal.getsignal(signal.SIGTERM)
signal.signal(signal.SIGTERM, sig_handler)
args = shlex.split(cmd_string)
# I want to handle the SIGTERM and if the cmd_string sends a SIGTERM then return a ret_code of -99
try:
p = subprocess.Popen(args, shell=False
, stdout=subprocess.PIPE
, stderr=subprocess.PIPE
)
out, err = p.communicate() # This fails if the cmd_string sends a SIGTERM
ret_code = p.returncode
except SigTermError:
ret_code = -99
finally:
signal.signal(signal.SIGTERM, original_sigterm_handler)
return ret_code
def worker(arg1, arg2):
""" Run db_command with 2 arguments. """
cmd_string = 'db_command -parameter1 {arg1} -parameter2 {arg2}'.format(arg1=arg1,arg2=arg2)
func_return = run_shell_command(cmd_string) # The whole process tree terminates if subprocess sends sigterm
if func_return == -99:
do_something_to_hanlde_sigterm()
else:
move_on()
if __name__ == '__main__':
processes = [mp.Process(target=worker, args=(x, x*x)) for x in list(range(4))]
for p in processes:
p.start()
for p in processes:
p.join()
print('All Done')