当前位置: 首页 > 知识库问答 >
问题:

python 通过发信号的方式杀死父进程,子进程仍然在运行,如何解决?

梁丘凯定
2024-04-04

a文件

import multiprocessingimport osimport signalimport timedef process1():    while True:        print("子进程运行中")        time.sleep(1)# 定义信号处理函数def handle_signal(signum, frame):    print(signum)    if signum == signal.SIGTERM:        print("Received SIGTERM signal. Deleting PID file...")        try:            os.remove("/var/run/crawler.pid")            print("PID file deleted successfully.")        except Exception as e:            print("Error deleting PID file:", e)# 注册信号处理函数signal.signal(signal.SIGTERM, handle_signal)if "__main__" == __name__:    a = multiprocessing.Process(target=process1)    a.daemon = True    a.start()    child_pid = a.pid    parent_pid = os.getpid()    with open("/var/run/crawler.pid", 'w') as f:        f.write(str(parent_pid))    a.join()    print("父进程pid:", parent_pid)    print("子进程pid", child_pid)    # os.waitpid(child_pid, 0)

b文件

import osimport signalwith open('/var/run/crawler.pid', 'r') as f:    try:        pid = int(f.read())        os.kill(pid, signal.SIGTERM)        print("Signal sent successfully to process", pid)    except Exception as e:        print("Error sending signal:", e)

共有1个答案

汪臻
2024-04-04
  1. 改用 os.getpgid 来获取主进程和子进程的进程组id 来储存

这里说明一下,据wiki了解到的资料信息,进程组是主进程和子进程组成的一个集合。

In a POSIX-conformant operating system, a process group denotes a collection of one or more processes.Among other things, a process group is used to control the distribution of a signal; when a signal is directed to a process group, the signal is delivered to each process that is a member of the group.

进程组的作用就是用来控制信号的分配到它的所有成员。所以你要杀掉主进程和相应的子进程,就要用 os.killpg 去向这个进程组去发送kill信号,否则常规的 os.kill 只能杀死单进程,而无法将信号量传递到子进程中,还需要你单独手动清除子进程。

  1. 将信号注册放在main里面创建子进程后
# a.pyimport multiprocessingimport osimport signalimport timedef process1():    while True:        print("子进程运行中")        time.sleep(1)# 定义信号处理函数def handle_signal(signum, frame):    print(signum)    if signum == signal.SIGTERM:        print("Received SIGTERM signal. Deleting PID file...")        try:            if os.path.exists("./crawler.pid"):                os.remove("./crawler.pid")                print("PID file deleted successfully.")        except Exception as e:            print("Error deleting PID file:", e)# 注册信号处理函数if "__main__" == __name__:    a = multiprocessing.Process(target=process1)    a.daemon = True    a.start()    child_pid = a.pid    parent_pid = os.getpid()    parent_pid_group = os.getpgid(parent_pid)    # 这里更改为进程组id    signal.signal(signal.SIGTERM, handle_signal)    # 从外面放入到main里面    with open("./crawler.pid", "w") as f:        f.write(str(parent_pid_group))    a.join()    print("父进程pid:", parent_pid)    print("子进程pid", child_pid)    # os.waitpid(child_pid, 0)

同样对另外一个文件修改:

# b.pyimport osimport signalwith open("./crawler.pid", "r") as f:    try:        pid = int(f.read())        os.killpg(pid, signal.SIGTERM)    # 这里换成killpg去执行操作        print("Signal sent successfully to process", pid)    except Exception as e:        print("Error sending signal:", e)
 类似资料:
  • 问题内容: 我从python脚本生成了5个不同的进程,如下所示: 我的问题是,当父进程(主脚本)以某种方式被杀死时,子进程继续运行。 当父进程被杀死时,有没有办法杀死这样生成的子进程? 编辑:我正在尝试: 但这似乎不起作用 问题答案: 我自己也遇到了同样的问题,我有以下解决方案: 打电话之前,您可以设置。然后如此处所述python.org multiprocessing 进程退出时,它将尝试终止其

  • 问题内容: 例如从bash: 仅杀死父进程。 问题答案: 当您将 负 PID传递给时,它实际上会通过该(绝对)数字将信号发送到过程 组 。您可以在Python中完成与之等效的操作。

  • 问题内容: 我在Python中使用子进程包运行一个子进程,以后需要杀死它。但是,子流程包的文档指出,terminate()函数仅从2.6起可用。 我们正在运行带有2.5的Linux,并且出于向后兼容的原因,我无法升级到2.6,替代品是什么?我猜这些功能是某些事情的便捷方法。 问题答案: 您在进程pid上调用os.kill。 您还可以,因为您使用的是Linux。Windows用户很不走运。

  • 我正在使用Javaexec运行bash脚本,但当我进入CTRL C时,Java进程将退出,子进程也将退出,如何在JVM关闭后保持子进程运行? 父母亲上海: 我已经在这里和这里阅读了类似问题的答案,例如,使用nohup在脚本运行命令中启动父bash脚本,或者使用trap命令来阻止信号,在我的研究中,它可以工作,例如“tail-f somefile”,但不适用于我的用例“ffmpeg-params”,

  • 问题内容: 我有一个程序生成并与CPU繁重,不稳定的进程通信,而不是由我创建的。如果我的应用程序崩溃或被杀死,我也希望子进程也被杀死,因此用户不必跟踪它们并手动杀死它们。 我知道以前已经讨论过该主题,但是我已经尝试了所有描述的方法,但似乎没有一种方法能够经受住测试的考验。 我知道这是有可能的,因为终端一直在这样做。如果我在终端中运行某些程序并杀死该终端,则这些东西总是会死掉。 我试过了,双叉和。不

  • 问题内容: 我正在python中使用subprocess模块​​运行一些shell脚本。如果shell脚本运行时间很长,我想杀死该子进程。我认为如果将其传递给我的陈述就足够了。 这是代码: 我已经用一些运行120秒的shell脚本测试了此调用。我期望子进程在30秒后被杀死,但是实际上该进程正在完成120秒脚本,然后引发了Timeout Exception。现在的问题是如何通过超时杀死子进程? 问题