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

a文件

import multiprocessing
import os
import signal
import time


def 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 os
import signal

with 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.4k
1 个回答
  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.py

import multiprocessing
import os
import signal
import time


def 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.py
import os
import signal

with 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)
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏