You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3从另一脚本停止运行脚本失效问题(树莓派GPIO场景)

问题排查与修复

问题根源

  1. 同步阻塞调用卡死主逻辑:subprocess.call()是同步方法,启动2ndPython.py后会一直等待它结束,主脚本完全无法响应按钮释放事件,自然触发不了停止逻辑。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 14:54:09