繁体   English   中英

子进程完成后停止Python脚本

[英]Python script being stopped after a subprocess is completed

运行脚本时,我正在动态运行一组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()时,它再次消失。 不管该子DO_THING()位于DO_THING()还是我注释掉所有内容,然后再次使其击中output = call("command", shell=True)行。 一旦再次使用子流程,它将停止。

人们发现有什么建议或方法可以阻止传递给我的脚本停止运行?

(仅提防您,我无权访问导致脚本停止的"command"的源,并且我正在使用的"command"并不重要,因为我不能为此做任何事情。我也必须使用此"command" 。)

您看到的消息表明您的子进程正在停止 ,而不是有错误。 例如,在外壳程序中启动进程后键入Ctrl-Z时,或等效地,使用kill命令向目标进程发送SIGTSTP信号时,就会发生这种情况。 据推测,您无权访问的command正在接收该信号。 它甚至可以将其发送给自己,尽管在不了解更多有关命令的情况下,只是猜测如何发生或为什么发生。

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

运行此代码段,您应该看到可以在终端中键入Ctrl-Z ,并且外壳程序应该显示[1]+ Stopped ...

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

但是,使用以下代码,您将看到信号被忽略,并且无论信号如何,该过程将继续“工作”(在这种情况下为睡眠)。 每当您按Ctrl-Z时,您应该只在外壳上看到^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示例一样,如果您Ctrl-Z ,您应该只看到^Z Ctrl-Z ,这表明信号被忽略了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM