Adafruit驱动无法兼容Python multiprocessing多进程模块问题咨询
问题根因
段错误由多进程创建时的硬件句柄继承失效导致:
- Linux平台下Python
multiprocessing默认使用fork方式创建子进程,该模式仅复制父进程的用户态内存,不会同步内核态持有的I2C总线文件描述符、硬件操作锁状态 - Adafruit传感器驱动底层为C实现的CircuitPython绑定,子进程复制得到的是失效的硬件操作句柄,调用读取接口时会直接访问非法内存地址,触发段错误
threading多线程模式下所有线程共享同一进程的内存空间与文件描述符,因此不会出现该异常
兼容方案
方案1:子进程内初始化硬件(推荐,稳定性最高)
不要在主进程全局作用域初始化I2C总线与传感器对象,将所有硬件初始化逻辑移到子进程执行函数内部,确保子进程独立申请合法的硬件操作句柄。
修正后可正常运行的多进程代码:
import time import board import adafruit_bno055 import multiprocessing def sensor_read_loop(): # 硬件初始化全部在子进程内部完成 i2c = board.I2C() sensor = adafruit_bno055.BNO055_I2C(i2c) while True: print("Quaternion: {}".format(sensor.quaternion)) time.sleep(0.05) # 根据采样需求加间隔,避免I2C总线占用过高 if __name__ == "__main__": # 多进程逻辑必须放在主入口判断内,避免跨平台递归启动问题 sensor_process = multiprocessing.Process(target=sensor_read_loop) sensor_process.start() sensor_process.join()
方案2:修改多进程启动模式
如果需要调整进程创建逻辑,可以将默认的fork启动模式改为spawn,该模式会启动全新的Python解释器进程,不会继承父进程的失效句柄。注意该模式下依然不能直接跨进程复用父进程初始化的传感器对象,子进程仍需独立初始化硬件。
设置方式:
import multiprocessing # 该配置必须在所有进程创建操作之前执行 multiprocessing.set_start_method("spawn")
方案3:单进程读硬件+进程间通信分发数据
如果多个业务进程需要使用传感器数据,不要让多个进程直接操作I2C总线:单独启动一个进程负责传感器读取,通过multiprocessing.Queue/Pipe把采样数据分发给其他业务进程,既避免段错误,也能防止多进程抢占总线导致的通信异常。
注意:所有多进程代码必须包裹在
if __name__ == "__main__":判断块内,否则在Windows、macOS平台会出现进程递归启动的问题。
内容的提问来源于stack exchange,提问作者KCC
相关产品推荐
相关产品推荐

