调用subprocess.call后如何保持Python主循环持续运行?
问题解决:启动子进程后主脚本持续监控
场景说明
编写了一个Python监控脚本,通过读取check.txt文件内容(start或stop)来启动或终止test.py脚本:
- 主脚本负责循环检查指令,控制
test.py的启停 test.py启动时会将自身PID写入pid.txt,供主脚本识别
现有问题
当test.py未运行时,写入start到check.txt后,主脚本会卡在subprocess.call()语句处,无法继续执行后续的循环监控逻辑。
核心原因
subprocess.call()是阻塞式调用,它会等待子进程(test.py)执行完毕后才会返回,但test.py是一个无限循环脚本,所以主进程会一直被阻塞,无法继续后续的监控流程。
解决方案
使用subprocess.Popen()替代subprocess.call(),Popen()是非阻塞式调用,启动子进程后会立即返回,主进程可以继续执行循环逻辑。同时还要处理几个细节问题:
1. 替换阻塞调用为非阻塞调用
将call()替换为Popen(),无需等待子进程结束。
2. 处理指令读取的换行符问题
readline()读取的内容会包含末尾的换行符\n,需要用strip()去除,避免指令匹配失败。
3. 补全缺失的模块导入
主脚本中使用了os.kill()但未导入os模块,需要添加import os。
修改后的主脚本代码
import psutil import time import os from subprocess import Popen # 替换call为Popen while True: with open('check.txt') as f: # 去除换行符,确保指令匹配准确 order = f.readline().strip() with open('pid.txt') as f: try: pid = int(f.readline().strip()) except ValueError: # 处理pid.txt为空或无效的情况 pid = 0 if order == 'stop': if pid != 0 and psutil.pid_exists(pid): os.kill(pid, 9) print(f"Stopped process with PID {pid}") elif order == 'start': if pid == 0 or not psutil.pid_exists(pid): print('Starting script') # 使用Popen启动非阻塞子进程 Popen(["C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\python.exe", "test.py"]) print('Checking again in 10 secs...') time.sleep(10)
补充说明
Popen()启动子进程后,主脚本会立刻回到循环,继续监控check.txt的指令- 增加了
pid的异常处理,避免pid.txt内容无效时引发报错 - 指令读取时的
strip()确保了start/stop的匹配不会因为换行符失败
内容的提问来源于stack exchange,提问作者Claytor
相关产品推荐
相关产品推荐

