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

作者站长头像
站长
· 阅读数 4

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个回答
avatar
test
2024-06-20
  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)
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容