如何从Python subprocess.Popen实例获取进程结束时间戳?
获取subprocess.Popen子进程的准确结束时间戳
由于subprocess.Popen实例本身不会保存进程的结束时间戳,你需要在检测到进程结束的第一时间主动记录,这里有两个靠谱的实现方案:
方案一:定时检查时记录结束时间
利用你现有的定时poll()检查逻辑,在存储进程的字典里给每个进程额外维护一个end_time字段(初始为None)。每次检查时,若进程未记录结束时间且poll()返回非None(说明进程已结束),立刻用当前时间戳填充end_time。
示例代码:
import time import subprocess # 进程存储字典,每个条目包含进程实例、启动时间、结束时间 processes = {} # 启动子进程的逻辑 def start_process(proc_id, cmd): popen = subprocess.Popen(cmd, shell=True) processes[proc_id] = { "popen": popen, "start_time": time.time(), "end_time": None } # 定时检查进程的逻辑 def check_running_processes(): for proc_id, info in processes.items(): if info["end_time"] is None: exit_code = info["popen"].poll() if exit_code is not None: # 进程已结束,记录当前时间作为结束时间 info["end_time"] = time.time() print(f"进程{proc_id}结束,结束时间戳:{info['end_time']}")
这个方案的误差最多等于你的检查间隔(比如5秒、5分钟),如果对时间精度要求不是极高,完全够用,而且不需要额外引入线程,逻辑简单。
方案二:用线程实时监听进程结束
如果需要更精确的结束时间(几乎和进程实际结束时刻一致),可以给每个子进程配一个守护线程,线程调用popen.wait()阻塞等待进程结束,一旦进程退出就立刻记录时间戳。
示例代码:
import threading import time import subprocess # 进程存储字典 processes = {} def monitor_process(proc_info): # 阻塞等待进程结束 proc_info["popen"].wait() # 进程结束时立即记录时间戳 proc_info["end_time"] = time.time() print(f"进程结束,结束时间戳:{proc_info['end_time']}") # 启动子进程的逻辑 def start_process(proc_id, cmd): popen = subprocess.Popen(cmd, shell=True) proc_info = { "popen": popen, "start_time": time.time(), "end_time": None } # 启动守护线程,不阻塞主进程 monitor_thread = threading.Thread(target=monitor_process, args=(proc_info,), daemon=True) monitor_thread.start() processes[proc_id] = proc_info
这个方案的时间戳精度极高,因为进程一结束就会被捕获记录,而且守护线程会随着主进程退出自动结束,不会占用额外资源。
为什么不推荐日志文件修改时间
你之前尝试的日志最后修改时间方法确实存在明显缺陷:一是部分子进程不生成日志,二是日志写入可能滞后于进程实际结束时间,三是频繁读取文件属性会带来额外性能开销,远不如直接在进程结束时主动记录时间可靠。
内容的提问来源于stack exchange,提问作者Milan
相关产品推荐
相关产品推荐

