Python中如何获取发送SIGTERM信号的进程PID?
最近测试环境遇到个问题,用 Python 服务老是被 SIGTERM 信号终止了,已经基本排查了是服务自己把自己干掉了,所以想用 python signal 模块捕一下 SIGTERM 信号,但是还有找到能记录下 SIGTERM 信号来自哪个进程的方法,大家有没有做过类似的功能呀,求教。或者能另辟蹊径分析到 SIGTERM 来源的方法也欢迎赐教。 感谢。
Python中如何获取发送SIGTERM信号的进程PID?
不能。不可能的。
在Python里,如果你想获取那个给你当前进程发送了SIGTERM信号的进程PID,标准库的signal模块能帮上忙。不过,它没法直接告诉你发送者的PID,因为SIGTERM这类信号通常不携带这个信息。
但是,你可以用signal.signal()设置一个信号处理器,当SIGTERM到来时,通过其他系统调用(比如os.getpid()获取自己的PID,或者用subprocess和ps命令组合去查)来间接推断。最常见的情况是父进程(比如shell或进程管理器)发送的SIGTERM,这时你可以用os.getppid()获取父进程的PID。
下面是一个简单的示例,演示如何捕获SIGTERM并打印可能的发送者信息:
import signal
import os
import sys
import time
def sigterm_handler(signum, frame):
# 当收到SIGTERM时,打印当前进程PID和父进程PID
print(f"\n进程 {os.getpid()} 收到了 SIGTERM 信号。")
print(f"父进程PID (可能的发送者): {os.getppid()}")
# 这里可以添加其他逻辑,比如清理资源
sys.exit(0)
# 设置SIGTERM的信号处理器
signal.signal(signal.SIGTERM, sigterm_handler)
print(f"当前进程PID: {os.getpid()}")
print("运行中,等待信号... 按 Ctrl+C 可手动结束。")
# 保持程序运行,等待信号
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\n收到 KeyboardInterrupt,退出。")
核心点:
signal.signal(signal.SIGTERM, sigterm_handler)这行是关键,它把sigterm_handler函数注册为SIGTERM信号的处理函数。- 在处理器里,
os.getppid()返回父进程的PID。在大多数由shell或init系统发送SIGTERM的情况下,这个父进程PID就是发送者。 - 如果信号来自系统其他部分(比如
kill命令或进程管理器),这个PID可能不是直接的发送者,但通常是发送链条中的关键一环。
一句话总结: 用signal模块捕获SIGTERM,在处理器里通过os.getppid()获取父进程PID作为最可能的发送者。
我记得 signal 模块也是很简单地封装一下系统信号处理的回调而已。
你这样的情况啊,用 bpftrace 试试看看?
你有看内核日志吗, 说不定被内核杀的
遇到过类似问题,某 C 扩展出现了 SIGSEGV,日志里就能发现了
看错了,SIGTERM 应该还不一样,忽略上一条
好的,感谢
是的,signal 封得比较简易,我试一下你说的 bprtrace,感谢指教!
看过,没有线索😬
好的,感谢交流
如果是用的 python3.3 及以上版本的话,可以使用 signal.sigwaitinfo
返回结果中包含 siginfo_t 这个数据结构,其中有 si_pid,si_uid 字段,分别为信号发出的 pid 和 用户 id
我简单测试了一下,可以拿到 pid
感谢

