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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:45:40