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

Python进程变量传递与进程控制代码修改技术求助

问题分析与解决方案

首先得明确你遇到的核心问题:multiprocessing和threading的内存模型完全不同——线程共享同一进程的内存空间,所以全局变量/实例变量能直接生效;但每个子进程会复制父进程的内存,你在主进程修改的self.RunningSys和子进程里的那个变量根本不是同一个东西,自然控制不了。

另外你的代码还有几个关键错误:

  • MProc里你创建了一个全新的TestClass()实例来跑Testloop,而且target=TestClass().Testloop()会直接在主进程执行这个方法(因为加了括号),而不是把方法交给子进程去执行。
  • 独立脚本里你创建了两个完全独立的TestClass实例:一个调用MProc启动进程,另一个调用StopPr,后者修改的是自己的RunningSys,和跑进程的那个实例毫无关系。

修正方案:用multiprocessing.Event实现跨进程控制

Event是multiprocessing提供的跨进程同步原语,能安全地在主进程和子进程之间传递"停止"信号。下面是修正后的代码:

类定义文件(testfile.py)

import RPi.GPIO as GPIO
from RPi.GPIO import LOW, OUT, HIGH, BCM
import multiprocessing as mp
import time

class TestClass():
    def __init__(self, PinOne=22, PinTwo=27):
        self.PinOne = PinOne
        self.PinTwo = PinTwo
        # 用Event代替普通布尔变量,支持跨进程通信
        self.stop_event = mp.Event()
        GPIO.setmode(BCM)
        GPIO.setup(PinOne, OUT)
        GPIO.output(PinOne, LOW)
        GPIO.setup(PinTwo, OUT)
        GPIO.output(PinTwo, LOW)
        
    def Testloop(self):
        # 检查Event是否被设置,未设置则继续循环
        while not self.stop_event.is_set():
            GPIO.output(self.PinOne, HIGH)
            GPIO.output(self.PinTwo, HIGH)
            time.sleep(1)
            GPIO.output(self.PinOne, LOW)
            GPIO.output(self.PinTwo, LOW)
        # 循环结束后清理GPIO
        GPIO.cleanup()
        
    def StopPr(self):
        # 设置Event,触发子进程停止
        self.stop_event.set()
        
    def MProc(self):
        # 注意:target传方法对象(不带括号)
        # 这里用当前实例的Testloop,而不是新建实例
        self.mpgp = mp.Process(target=self.Testloop)
        self.mpgp.start()
        # 不要在这里调用join(),否则主进程会阻塞到子进程结束,没法执行后续的StopPr

独立脚本

from testfile import TestClass
import time

# 创建同一个实例,而不是两个不同的
test_instance = TestClass()
# 启动子进程
test_instance.MProc()
# 等待4秒
time.sleep(4)
# 发送停止信号
test_instance.StopPr()
# 等待子进程结束
test_instance.mpgp.join()

关键修改点说明

  1. 用mp.Event替代布尔变量:Event是跨进程可见的,主进程调用set()后,子进程的is_set()会立刻返回True,触发循环终止。
  2. 修正进程创建方式:target要传方法对象(self.Testloop),而不是直接调用方法(TestClass().Testloop()),否则方法会在主进程直接执行,子进程根本不会启动。
  3. 使用同一个实例:独立脚本里必须操作同一个TestClass实例,否则StopPr修改的是另一个实例的Event,和子进程无关。
  4. 移除MProc里的join():join()会阻塞主进程,直到子进程结束,这样你就没法在后续调用StopPr了,应该把join()放到发送停止信号之后。
  5. 修正GPIO引用:Testloop里要使用self.PinOne和self.PinTwo,否则会报错找不到变量。

内容的提问来源于stack exchange,提问作者Hojo.Timberwolf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:44:56