子进程完成后,Python脚本将停止

问题描述 投票:2回答:1

运行我的脚本时,我正在动态运行一组for循环。基本上调用项目列表,检查该项目需要运行的“阶段”,然后按顺序运行它们。当我尝试运行这些循环时,它会通过第一个对象,然后在终端中给出“[1] + Stopped Script.py”。我已经找到了开始备份我的脚本的方法,但没有关于如何完全避免这种情况的帖子。

我尝试过使用Popencallcheck_output等。他们都得到了相同的结果。我确信这是我正在调用的另一个项目,它在结尾处执行此操作,但我不认为关闭的另一个程序应该杀死我的脚本,尤其是不在子进程中。

我也尝试过使用线程和多处理。两者都无济于事。

def foo(list):
    stages = 0
    for c in things:
        info = load_json_info(c)
        if info["stage"] >= stages:
            stages = info["stage"]
    for p in list:
        use_list(p)
    stages = stages + 1
    for i in range(stages):
        for b in list:
            info = load_json_info(b)
            if info["stage"] == i:
                if info["check"] != "NO":
                    output = call("command", shell=True)
                    if output == 0:
                        DO_THING()
                    else:
                        DONT_DO_THING()
                else:
                    DONT_DO_THING()

它到达了DO_THING()并经历了所有这些,然后当它再次调用另一个子进程时,它会再次消失。是否该子进程生活在DO_THING()或我评论所有内容,并让它再次击中output = call("command", shell=True)线。一旦再次使用子进程,它就会停止。

人们发现阻止任何传递以阻止我的脚本的任何建议或方法?

(就像一个抬头,我无法访问导致我的脚本停止的"command"的来源,而我使用的"command"并不重要,因为我不能做任何事情。我必须使用这个"command"同样。)

python subprocess
1个回答
0
投票

您看到的消息表明您的子进程正在停止,而不是存在错误。例如,在shell中启动进程后键入Ctrl-Z时,或者等效地使用SIGTSTP命令向目标进程发送kill信号时会发生这种情况。据推测,您无法访问的command正在接收此信号。它甚至可以将它发送给自己,虽然不知道更多关于命令的信息,但这只是关于如何或为何发生这种情况的猜测。

您可以使用signal模块,特别是pthread_sigmask()函数,选择在Python中忽略此信号。一个指定信号掩码,以及如何处理它们。在这种情况下,您要忽略SIGTSTP信号,可以使用:signal.pthread_sigmask(signal.SIG_BLOCK, (signal.SIGTSTP,))。 (后一个参数实际上是一系列要忽略的信号。)

运行这段代码,您应该看到可以在终端中键入Ctrl-Z,shell应该显示[1]+ Stopped ...

import time
duration = 5.0
print('Sleeping for {:0.2f} seconds'.format(duration))
time.sleep(duration)

但是,使用以下代码,可以看到信号被忽略,并且无论信号如何,该过程将继续“工作”(在这种情况下为睡眠)。只要你按下^Z,你就应该在shell上看到Ctrl-Z

import time
import signal
duration = 5.0
print('Sleeping for {:0.2f} seconds, ignoring SIGTSTP'.format(duration))
signal.pthread_sigmask(signal.SIG_BLOCK, (signal.SIGTSTP,))
time.sleep(duration)

要在脚本中实际使用它,请在调用相关的command之前忽略该信号。最好事先查询进程的信号掩码,并在完成command后将其重置为该值。您应该查看signal(3)sigprocmask(2)kill(2)的手册页,以获取有关信号和过程的更多信息。

编辑Python <= 2.7

signal.pthread_sigmask是在Python 3.3中添加的。应该适用于早期版本的解决方案是通过安装执行此操作的处理程序来直接忽略该信号。例如:

import signal
import time

duration = 5.0
signal.signal(signal.SIGTSTP, signal.SIG_IGN)
print 'Sleeping for %f seconds, ignoring SIGTSTP' % duration
time.sleep(duration)

与上面的3.3示例一样,如果你点击^Z,你应该只看到Ctrl-Z,表明信号被忽略了。

© www.soinside.com 2019 - 2024. All rights reserved.