Yolov/main.py

183 lines
5.8 KiB
Python
Raw Normal View History

2025-12-11 13:41:07 +08:00
# main.py
2025-11-26 13:55:04 +08:00
# 主程序入口
import os
import signal
import threading
2025-12-11 15:08:28 +08:00
import time
import schedule
2025-11-26 13:55:04 +08:00
import torch
from log import logger
2025-12-11 13:41:07 +08:00
from global_data import gd
2025-11-26 13:55:04 +08:00
from server import socketio, app
2025-12-11 13:41:07 +08:00
from task_manager import task_manager
2025-11-26 13:55:04 +08:00
2025-12-11 13:41:07 +08:00
# 初始化全局数据
2025-11-26 13:55:04 +08:00
gd._init()
2025-12-11 13:41:07 +08:00
# 设置全局变量
gd.set_value('task_manager', task_manager) # 直接在这里初始化
2025-11-26 13:55:04 +08:00
gd.set_value('latest_drone_data', None)
gd.set_value('mqtt_data_lock', threading.Lock())
2025-12-11 13:41:07 +08:00
# 初始化任务管理器
logger.info("任务管理器初始化...")
logger.info(f"任务管理器实例: {task_manager}")
2025-12-11 15:08:28 +08:00
def cleanup_stopped_tasks():
"""定期清理已停止的任务"""
try:
if not task_manager:
return
# 取得所有任务
2025-12-11 15:08:28 +08:00
all_tasks = task_manager.get_all_tasks()
# 计数
2025-12-11 15:08:28 +08:00
cleaned_count = 0
for task in all_tasks:
# 取得任务ID
2025-12-11 15:08:28 +08:00
task_id = task.get('task_id')
# 取得任务状态
2025-12-11 15:08:28 +08:00
status = task.get('status', 'unknown')
# 清理已停止、失败或错误的任务
if status in ['stopped', 'failed', 'error']:
# 检查任务线程是否真的已经停止
thread = task_manager.tasks.get(task_id, {}).get('thread')
if thread and hasattr(thread, 'is_alive'):
if not thread.is_alive():
if task_manager.cleanup_task(task_id):
cleaned_count += 1
else:
if task_manager.cleanup_task(task_id):
cleaned_count += 1
if cleaned_count > 0:
logger.info(f"定时清理已完成,清理了 {cleaned_count} 个任务")
except Exception as e:
logger.error(f"定时清理任务失败: {str(e)}")
def start_cleanup_scheduler():
"""启动定时清理调度器"""
if not schedule:
logger.warning("schedule模块不可用跳过定时清理调度器")
return
2025-12-11 15:08:28 +08:00
try:
# 每5分钟清理一次
schedule.every(5).minutes.do(cleanup_stopped_tasks)
# 每分钟检查一次待清理任务
schedule.every(1).minutes.do(check_pending_cleanup)
def run_scheduler():
while True:
try:
schedule.run_pending()
except Exception as e:
logger.error(f"定时任务执行失败: {str(e)}")
#time.sleep(60) # 每分钟检查一次
time.sleep(1) # 缩短为1秒检查频率
scheduler_thread = threading.Thread(target=run_scheduler, daemon=True)
scheduler_thread.start()
logger.info("定时清理调度器已启动")
except Exception as e:
logger.error(f"启动定时清理调度器失败: {str(e)}")
2025-12-11 15:08:28 +08:00
def check_pending_cleanup():
"""检查待清理的任务"""
try:
if not task_manager:
return
# 检查是否有长时间处于停止状态但未清理的任务
for task_id, task_info in task_manager.tasks.items():
status = task_info.get('status', 'unknown')
last_updated = task_info.get('last_updated', 0)
if status == 'stopped' and time.time() - last_updated > 60: # 停止超过60秒
logger.info(f"发现长时间停止未清理的任务: {task_id}")
task_manager.cleanup_task(task_id)
except Exception as e:
logger.error(f"检查待清理任务失败: {str(e)}")
2025-12-11 13:41:07 +08:00
# main.py 修改部分
2025-11-26 13:55:04 +08:00
if __name__ == '__main__':
2025-12-11 13:41:07 +08:00
logger.info("启动多任务版YOLOv8服务")
# 打印PyTorch版本和CUDA可用性
2025-11-26 13:55:04 +08:00
logger.info(f"PyTorch版本: {torch.__version__}, CUDA可用: {torch.cuda.is_available()}")
2025-12-11 13:41:07 +08:00
2025-12-11 15:08:28 +08:00
# 启动定时清理
start_cleanup_scheduler()
2025-12-11 13:41:07 +08:00
# 初始化任务推流管理器
try:
from task_stream_manager import task_stream_manager
task_stream_manager.start_health_monitor()
logger.info("任务推流管理器初始化完成")
except Exception as e:
logger.error(f"初始化推流管理器失败: {str(e)}")
2025-11-26 13:55:04 +08:00
# 退出服务
def graceful_exit(signum, frame):
2025-12-11 13:41:07 +08:00
logger.info("收到退出信号,停止所有服务...")
# 停止所有任务推流
try:
from task_stream_manager import task_stream_manager
if 'task_stream_manager' in globals():
task_stream_manager.cleanup_all()
except Exception as e:
logger.error(f"清理推流管理器失败: {str(e)}")
2025-12-11 13:41:07 +08:00
# 停止所有任务
try:
if task_manager:
cleaned_count = task_manager.cleanup_all_tasks()
logger.info(f"清理了 {cleaned_count} 个任务")
except Exception as e:
logger.error(f"清理任务管理器失败: {str(e)}")
2025-12-11 13:41:07 +08:00
2025-11-26 13:55:04 +08:00
logger.info("服务已退出")
os._exit(0)
# Windows平台特殊处理信号
try:
if os.name != 'nt': # Unix/Linux/Mac
signal.signal(signal.SIGINT, graceful_exit)
signal.signal(signal.SIGTERM, graceful_exit)
else: # Windows
# Windows下使用键盘中断处理
import atexit
atexit.register(lambda: graceful_exit(None, None))
except Exception as e:
logger.error(f"注册退出处理函数失败: {str(e)}")
2025-11-26 13:55:04 +08:00
2025-12-11 13:41:07 +08:00
# 启动服务
try:
socketio.run(app,
host='0.0.0.0',
port=9309,
debug=True,
use_reloader=False,
allow_unsafe_werkzeug=True)
except KeyboardInterrupt:
logger.info("收到键盘中断信号")
graceful_exit(None, None)
except Exception as e:
logger.error(f"启动服务失败: {str(e)}")
import traceback
logger.error(traceback.format_exc())