树莓派3B+ Python脚本手动运行正常 crontab开机自启报deque突变错误
问题原因分析
- crontab
@reboot规则的执行时机过早,此时树莓派的GPIO驱动、硬件外设还未完成初始化,PIR传感器刚上电也未完成校准,gpiozero库的MotionSensor内部状态队列还未稳定就被主线程读取,触发队列迭代过程中被后台更新线程修改的并发冲突,也就是报错里的RuntimeError: deque mutated during iteration。 - 手动执行时系统已经完成所有硬件初始化,传感器也完成了上电校准,因此不会触发该并发冲突。
- 额外注意crontab的执行环境和登录shell的环境不同,也可能存在依赖加载异常的问题,但本次报错明确指向硬件初始化阶段的并发问题。
解决方案
1. 给启动脚本加前置延迟,等待硬件初始化完成
修改launcher.sh,在执行Python脚本前加10秒左右的等待,适配系统和传感器的初始化时长:
#!/bin/sh #launcher.sh cd /home/pi/SummerSeries2021 sleep 10 sudo python3 Main.py cd /
如果启动仍失败可适当延长延迟时间到20-30秒,匹配PIR传感器的上电校准周期。
2. 优化Python脚本的初始化逻辑
在初始化PIR传感器后添加等待稳定的逻辑,避免立刻读取传感器状态触发并发异常,修改Main.py对应部分:
pirS = MotionSensor(4) pirB = MotionSensor(21) # 新增传感器稳定等待逻辑 time.sleep(5) pirS.wait_for_no_motion() pirB.wait_for_no_motion()
3. 优化crontab规则(可选)
原crontab规则中日志路径为相对路径,可能出现路径解析失败无法写入日志的问题,修改为绝对路径:
@reboot sh /home/pi/SummerSeries2021/launcher.sh >/home/pi/logs/cronlog 2>&1
4. 替换更可靠的自启方案(推荐)
crontab的@reboot本身可靠性较低,推荐使用systemd配置自定义服务,可明确设置启动依赖,确保在系统硬件、用户服务初始化完成后再运行脚本,还支持异常自动重启:
- 创建服务文件
/etc/systemd/system/motor-sensor.service:[Unit] Description=PIR Sensor Motor Controller After=multi-user.target [Service] Type=simple ExecStart=/usr/bin/python3 /home/pi/SummerSeries2021/Main.py User=root Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target - 执行命令开启自启:
sudo systemctl daemon-reload sudo systemctl enable motor-sensor.service sudo systemctl start motor-sensor.service
5. 更新gpiozero库版本
旧版本的gpiozero存在MotionSensor队列操作的并发bug,可执行命令更新到最新版本:
sudo pip3 install -U gpiozero
内容的提问来源于stack exchange,提问作者Kahlaoui
相关产品推荐
相关产品推荐

