GNU Parallel 和 Python 的 atexit

3

我尝试使用GNU parallel运行一个Python脚本,似乎一切正常,除了在Python脚本中使用的atexit例程。似乎在ctrl+c之后,parallel会杀死Python进程而不给Python调用已注册的atexit例程的机会。

如何让parallel对子进程更友好?

这里有一个示例来展示这种行为。

test_signal.py:

#!/usr/bin/env python3

import time
import sys
import atexit

def cleanup():
    print('cleanup called', flush=True)

atexit.register(cleanup)

time.sleep(60)
print('completed process', sys.argv[1])

使用以下命令进行测试:

chmod +x test_signal.py
./test_signal.py 1 # this works as expected when using ^C
parallel -j 4 ./test_signal.py {} ::: $(seq 1 12) # this one does not

当你让计时器倒计时结束时,它是否运行清理操作?(等待60秒) - Almog-at-Nailo
是的,无论是否并行,正常退出时都会调用清理函数(没有ctrl+c)。 - Axeon Thra
尝试使用killall -HUP parallel代替Ctrl-C。 - Mark Setchell
显然,parallel是一个perl脚本。因此,killall -HUP parallel报告“parallel: no process found”。我尝试使用kill -HUP <pid>。它停止并显示消息“Hangup”。但没有清理。 - Axeon Thra
1
好的,抱歉。我们得等奥勒了。 - Mark Setchell
1个回答

3

GNU Parallel根据--termseq中指定的方式终止进程。默认值为:

TERM,200,TERM,100,TERM,50,KILL,25

因此,发送SIGTERM信号,等待200毫秒,发送SIGTERM信号,等待100毫秒,发送SIGTERM信号,等待50毫秒,发送SIGKILL信号,等待25毫秒。如果进程在等待期间死亡,则GNU Parallel将忽略序列中的其余部分-没有必要杀死已经死亡的进程。

--termseq更改为您想要发送的信号以及它们之间的时间间隔。

CTRL-C发送SIGINT信号,因此这应该有效:

# Give 1 second to clean up, then kill
parallel --termseq INT,1000,KILL,25 ...

请注意,除非你使用--ungroup,否则你将看不到输出结果。


太好了,它起作用了。我之前尝试过 --termseq。但是缺少了 ungroup 命令。非常感谢。 - Axeon Thra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接