树莓派中作为服务运行的脚本CPU占用过高及人员抓拍代码优化咨询
Raspberry Pi人员进出拍照脚本服务CPU占用过高的解决方案
看起来你这段用于检测房间人员进出并触发拍照的RPi脚本,在以服务形式运行时遇到了CPU占用过高的问题。结合你给出的代码片段,我来帮你分析根源并给出可行的解决办法:
首先贴出你的代码片段方便参考:
import RPi.GPIO as GP import os import socket def opencallback(channel): print(GP.input(channel)) if GP.input(channel): global closeEvent closeEvent = 1 else: global openEvent openEvent = 1 def transmit(message): s = socket.create_connection((host, port)) s.send(message) s.close() def capture(cam, gpiolist, quick): GP.output(cam1, gpiolist[0]) GP.output(cam2, gpiolist[1]) GP.out...
问题根源分析
最可能导致高CPU占用的原因有以下几点:
- 轮询式GPIO检测:如果你的主循环是通过不断循环检查GPIO状态或者全局变量
closeEvent/openEvent来触发逻辑,会让CPU一直处于满负荷运行状态,这是嵌入式脚本高CPU的头号元凶。 - 全局变量的频繁轮询:代码里用全局变量传递事件的方式,会迫使主循环高频读取这些变量,持续消耗CPU资源。
- 未完善的
capture函数:从片段看capture未写完,如果里面存在不合理的循环或阻塞逻辑,也会加重CPU负担。
针对性解决方案
1. 改用GPIO边缘检测(中断)替代轮询
RPi.GPIO支持硬件级的边缘检测,无需主循环持续轮询,只有当GPIO状态发生变化(上升沿/下降沿)时才触发回调。修改GPIO初始化逻辑:
import time # 记得导入time模块 # 初始化GPIO GP.setmode(GP.BCM) sensor_pin = 17 # 替换成你的传感器实际引脚 GP.setup(sensor_pin, GP.IN, pull_up_down=GP.PUD_UP) # 绑定边缘检测回调,bouncetime=200用于消除传感器抖动,避免误触发 GP.add_event_detect(sensor_pin, GP.BOTH, callback=opencallback, bouncetime=200) # 主循环只需保持进程存活,休眠几乎不占用CPU try: while True: time.sleep(3600) # 休眠1小时,可按需调整 except KeyboardInterrupt: GP.cleanup() # 退出时清理GPIO资源
2. 优化事件处理逻辑,移除全局变量
把拍照和传输逻辑直接放到回调函数里,不需要用全局变量传递事件,减少主循环的无用操作:
def opencallback(channel): current_state = GP.input(channel) print(current_state) if current_state: # 门关闭时的操作 capture(cam1, [1, 0], False) transmit("Door closed") else: # 门打开时的操作 capture(cam2, [0, 1], False) transmit("Door opened")
3. 完善capture函数并添加合理休眠
确保拍照操作完成后添加短暂休眠,避免短时间内重复触发拍照,同时补充完整的GPIO操作:
def capture(cam, gpiolist, quick): GP.output(cam1, gpiolist[0]) GP.output(cam2, gpiolist[1]) # 调用raspistill拍照,示例参数可按需调整 os.system("raspistill -o /var/log/door_events/$(date +%Y%m%d_%H%M%S).jpg -w 1280 -h 720 -t 100") # 休眠1秒,防止连续触发 time.sleep(1) # 拍照完成后可重置GPIO状态(如果需要) GP.output(cam1, 0) GP.output(cam2, 0)
4. 优化服务优先级(针对systemd管理的服务)
如果你的脚本是通过systemd作为服务运行,可调整服务的Nice值降低进程优先级,避免抢占系统资源:
编辑你的服务文件(比如/etc/systemd/system/door-camera.service),在[Service]段添加:
[Service] Nice=10 # 值越大优先级越低,范围-20到19
然后重新加载配置并重启服务:
sudo systemctl daemon-reload sudo systemctl restart door-camera.service
按照这些步骤调整后,你的脚本CPU占用率应该会降到很低的水平,同时保持功能正常运行。
内容的提问来源于stack exchange,提问作者Simon Marcoux
相关产品推荐
相关产品推荐

