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()
关键修改点说明
- 用
mp.Event替代布尔变量:Event是跨进程可见的,主进程调用set()后,子进程的is_set()会立刻返回True,触发循环终止。 - 修正进程创建方式:
target要传方法对象(self.Testloop),而不是直接调用方法(TestClass().Testloop()),否则方法会在主进程直接执行,子进程根本不会启动。 - 使用同一个实例:独立脚本里必须操作同一个
TestClass实例,否则StopPr修改的是另一个实例的Event,和子进程无关。 - 移除
MProc里的join():join()会阻塞主进程,直到子进程结束,这样你就没法在后续调用StopPr了,应该把join()放到发送停止信号之后。 - 修正GPIO引用:
Testloop里要使用self.PinOne和self.PinTwo,否则会报错找不到变量。
内容的提问来源于stack exchange,提问作者Hojo.Timberwolf
相关产品推荐
相关产品推荐

