Python3从另一脚本停止运行脚本失效问题(树莓派GPIO场景)
问题排查与修复
问题根源
- 同步阻塞调用卡死主逻辑:
subprocess.call()是同步方法,启动2ndPython.py后会一直等待它结束,主脚本完全无法响应按钮释放事件,自然触发不了停止逻辑。 pkill参数错误:-f需要完整的命令字符串作为匹配条件,原代码将python3和2ndPython.py拆分为两个参数,导致pkill找不到目标进程。
修复后的主脚本(脚本1)
import RPi.GPIO as GPIO import time import subprocess from subprocess import check_call buttonPin = 5 GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(buttonPin, GPIO.IN) try: run = 0 child_proc = None while True: # 按钮按下且未运行脚本时启动 if GPIO.input(buttonPin) == 0 and run == 0: print("Button pressed - start second script") # 用Popen创建异步子进程,不阻塞主逻辑 child_proc = subprocess.Popen(['python3', "2ndPython.py"]) run = 1 # 等待按钮释放(防抖) while GPIO.input(buttonPin) == 0: time.sleep(0.01) # 按钮释放且脚本运行中时停止 if GPIO.input(buttonPin) == 1 and run == 1: run = 0 print("Button released - kill second script") # 直接通过子进程对象终止(精准无副作用) if child_proc: child_proc.terminate() child_proc.wait() # 清理僵尸进程 # 备用方案:修复后的pkill命令 # check_call(["pkill", "-9", "-f", "python3 2ndPython.py"]) # 等待按钮再次按下(防抖) while GPIO.input(buttonPin) == 1: time.sleep(0.01) except KeyboardInterrupt: # 中断时清理子进程 if child_proc: child_proc.terminate() GPIO.cleanup()
关键修改说明
- 替换
subprocess.call为Popen:异步启动子进程,主脚本能持续监听按钮状态,不再被阻塞。 - 保存子进程对象:用
child_proc记录子进程实例,调用terminate()直接终止,比pkill更安全,不会误杀其他Python进程。 - 修复
pkill参数:将匹配字符串合并为"python3 2ndPython.py",确保能精准定位目标进程(作为备用方案)。 - 增加中断清理:按下Ctrl+C时自动终止子进程,避免残留进程。
脚本2无需修改,保持原逻辑即可。
内容的提问来源于stack exchange,提问作者JSTAL
相关产品推荐
相关产品推荐

