""" 多配置组启动器 支持同时启动多个配置组的自动化程序 """ import multiprocessing import sys from config import config_manager from main_single import run_automation_for_group from utils.logger import logger, throttle import logging import time def main(): """主函数""" # 重新加载配置 config_manager.load_config() # 获取所有配置组 groups = config_manager.config.get('groups', []) if not groups: logger.error("❌ 没有找到任何配置组") logger.info("请先运行 gui_config.py 创建配置组") return # 询问要启动哪些配置组 logger.info("=" * 60) logger.info("🔥 多配置组启动器") logger.info("=" * 60) logger.info("\n可用配置组:") for i, group in enumerate(groups): active_mark = "✓" if group.get('active', False) else " " logger.info(f" [{i}] {active_mark} {group['name']}") logger.info(f" 串口: {group['serial_port']} | 采集卡: {group['camera_index']}") logger.info("\n选择启动方式:") logger.info(" 1. 启动所有活动配置组") logger.info(" 2. 启动所有配置组") logger.info(" 3. 选择特定配置组") logger.info(" 0. 退出") choice = input("\n请选择 (0-3): ").strip() selected_indices = [] if choice == "0": logger.info("👋 退出") return elif choice == "1": # 启动所有活动配置组 selected_indices = [i for i, g in enumerate(groups) if g.get('active', False)] if not selected_indices: logger.error("❌ 没有活动的配置组") return logger.info(f"\n✅ 将启动 {len(selected_indices)} 个活动配置组") elif choice == "2": # 启动所有配置组 selected_indices = list(range(len(groups))) logger.info(f"\n✅ 将启动所有 {len(selected_indices)} 个配置组") elif choice == "3": # 选择特定配置组 indices_input = input("请输入要启动的配置组索引(用逗号分隔,如: 0,1,2): ").strip() try: selected_indices = [int(x.strip()) for x in indices_input.split(',')] # 验证索引有效性 selected_indices = [i for i in selected_indices if 0 <= i < len(groups)] if not selected_indices: logger.error("❌ 没有有效的配置组索引") return logger.info(f"\n✅ 将启动 {len(selected_indices)} 个配置组") except ValueError: logger.error("❌ 输入格式错误") return else: logger.error("❌ 无效选择") return # 显示将要启动的配置组 logger.info("\n将要启动的配置组:") for idx in selected_indices: group = groups[idx] logger.info(f" • {group['name']} (串口:{group['serial_port']}, 采集卡:{group['camera_index']})") confirm = input("\n确认启动? (y/n): ").strip().lower() if confirm != 'y': logger.info("❌ 取消启动") return # 启动多进程 processes = [] for idx in selected_indices: group = groups[idx] logger.info(f"启动进程: {group['name']}...") process = multiprocessing.Process( target=run_automation_for_group, args=(idx,), name=f"Group-{idx}-{group['name']}" ) process.start() processes.append((idx, group['name'], process)) logger.info(f"✅ {group['name']} 已启动 (PID: {process.pid})") logger.info(f"\n✅ 成功启动 {len(processes)} 个配置组进程") logger.info("\n" + "=" * 60) logger.info("运行状态:") logger.info("=" * 60) # 监控进程状态 try: while True: alive_count = 0 for idx, name, proc in processes: if proc.is_alive(): alive_count += 1 else: logger.warning(f"⚠️ {name} 进程已退出 (退出码: {proc.exitcode})") if alive_count == 0: logger.info("\n所有进程已退出") break time.sleep(2) # 打印存活状态 alive_names = [name for idx, name, proc in processes if proc.is_alive()] if alive_names: # 每2秒节流一次状态行 throttle("multi_alive", 2.0, logging.INFO, f"📊 运行中: {', '.join(alive_names)} ({alive_count}/{len(processes)})") except KeyboardInterrupt: logger.warning("\n\n🛑 收到停止信号,正在关闭所有进程...") for idx, name, proc in processes: if proc.is_alive(): logger.info(f"正在停止 {name}...") proc.terminate() proc.join(timeout=5) if proc.is_alive(): logger.warning(f"强制停止 {name}...") proc.kill() logger.info(f"✅ {name} 已停止") logger.info("\n👋 所有进程已停止") if __name__ == "__main__": multiprocessing.freeze_support() # Windows下需要 main()