多台控制

This commit is contained in:
ray
2025-10-30 23:39:27 +08:00
parent 069613fe09
commit 7623e22e5c
9 changed files with 350 additions and 190 deletions

View File

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