Python如何实现低内存低CPU占用的无限循环监听Redis信号
方案推荐
最优方案:使用Redis Pub/Sub 事件驱动监听(最低CPU/内存占用)
你当前的无间隔轮询方案会持续发起Redis请求,空转占用大量CPU资源,而Redis原生的发布订阅模式完全适配你的控制场景,不需要轮询,空闲时CPU占用几乎为0,内存仅维持单个Redis连接,资源占用远低于循环轮询。
实现逻辑:
- 你的Tornado服务接收到网页按钮点击请求时,直接往指定Redis频道发布控制指令,无需修改Key值:
# Tornado 侧代码示例 client.publish("adb_control_channel", "go") # 发启动指令 # client.publish("adb_control_channel", "stop") # 发停止指令
- 后台运行的ADB控制脚本直接订阅该频道,收到指令后触发对应操作即可:
import redis import threading # 全局状态标记,用于控制长时间运行的任务 running_flag = False def adb_go_task(): global running_flag while running_flag: print('going!!') # 执行修图、发消息等ADB操作逻辑 client = redis.Redis(host='127.0.0.1', port=6379, decode_responses=True) pubsub = client.pubsub() pubsub.subscribe('adb_control_channel') for msg in pubsub.listen(): if msg['type'] != 'message': continue command = msg['data'] if command == 'go' and not running_flag: running_flag = True # 用线程跑任务避免阻塞消息监听 threading.Thread(target=adb_go_task, daemon=True).start() elif command == 'stop' and running_flag: running_flag = False print('waiting response...') # 执行停止后的清理逻辑
优势:
- 完全事件驱动,无空转消耗,空闲时CPU占用<0.1%,内存占用稳定在10MB以内
- 指令响应延迟在毫秒级,远高于轮询方案
- 不需要修改Redis配置,开箱即用
次优优化方案:轮询加休眠(不改现有逻辑的最小改动方案)
如果不想调整现有逻辑结构,只需要在每次Redis查询后加合理的休眠时间,即可大幅降低CPU占用:
import time while True: value = client.get('key').decode('ascii') if value == 'go': print('going!!') # 执行function1 elif value == 'stop': print('watting response...') # 执行function2 # 根据你能接受的最大响应延迟设置休眠时间,单位秒 time.sleep(0.2)
修改后CPU占用可降低90%以上,仅比事件驱动方案高一点,开发成本最低。
后台运行方案
Linux环境下可以直接用nohup python3 your_script.py &启动后台进程,或者用systemd配置成系统服务实现开机自启、异常自动重启;Windows环境下可以用NSSM工具将脚本注册为系统服务,稳定运行无弹窗。
内容的提问来源于stack exchange,提问作者AhKiu
相关产品推荐
相关产品推荐

