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个回答
test
2024-06-20
- 改用 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
只能杀死单进程,而无法将信号量传递到子进程中,还需要你单独手动清除子进程。
- 将信号注册放在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)
回复
适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容