RUN__IT # python线程池的使用模板

本文介绍如何使用Python的ThreadPoolExecutor进行线程任务管理,包括任务提交、回调函数设置及Future对象的方法如cancel、result等,实现多线程并发执行并获取执行结果。
import time
import threading


# 子线程要执行的方法
def test(value1, value2=5):
    print("%s threading is printed %s, %s" % (threading.current_thread().name, value1, value2))
    time.sleep(2)
    return 'finished'


# 回调方法,线程执行完成要执行的方法,此方法必须接受future这个参数,固定写法
def test_result(future):

    print(future.result())
    print(future.running())
    print(1)


if __name__ == "__main__":
    from concurrent.futures import ThreadPoolExecutor
    # threadPool = ThreadPoolExecutor(max_workers=4, thread_name_prefix="test_")
    threadPool = ThreadPoolExecutor(max_workers=10)
    for i in range(0, 10):
        future = threadPool.submit(test, i, i+2)
        # 不懂这个map和submit的区别
        # future = threadPool.map(test, [i], [i+5])
        future.add_done_callback(test_result)

    threadPool.shutdown(wait=True)


"""
    Future 提供了如下方法:
            cancel():取消该 Future 代表的线程任务。如果该任务正在执行,不可取消,则该方法返回 False;否则,程序会取消该任务,并返回 True。
            cancelled():返回 Future 代表的线程任务是否被成功取消。
            running():如果该 Future 代表的线程任务正在执行、不可被取消,该方法返回 True。
            done():如果该 Funture 代表的线程任务被成功取消或执行完成,则该方法返回 True。
            result(timeout=None):获取该 Future 代表的线程任务最后返回的结果。如果 Future 代表的线程任务还未完成,该方法将会阻塞当前线程,其中 timeout 参数指定最多阻塞多少秒。
            exception(timeout=None):获取该 Future 代表的线程任务所引发的异常。如果该任务成功完成,没有异常,则该方法返回 None。
            add_done_callback(fn):为该 Future 代表的线程任务注册一个“回调函数”,当该任务成功完成时,程序会自动触发该 fn 函数
    """

from fastapi import FastAPI, Request from fastapi.responses import HTMLResponse, JSONResponse from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from jinja2 import Environment, FileSystemLoader import json import asyncio from dotenv import load_dotenv from pathlib import Path import uvicorn from transformers import AutoTokenizer, AutoModelForCausalLM import torch # 导入数据库操作 import database BASE_DIR = Path(__file__).resolve().parent.parent #主文件夹地址 FRONTEND_DIR = BASE_DIR / "frontend" app = FastAPI() load_dotenv(dotenv_path= BASE_DIR / r"backend\MyAI.env") templates = Jinja2Templates(directory=str(FRONTEND_DIR)) # 挂载静态资源 app.mount("/static", StaticFiles(directory=str(FRONTEND_DIR)), name="static") # Jinja2 模板引擎(用于渲染 HTML) template_env = Environment(loader=FileSystemLoader(str(FRONTEND_DIR))) # 全局变量(在 app 启动时加载一次) model = None tokenizer = None def load_model(): """同步函数:实际加载模型""" model_name = str(BASE_DIR / "model\DeepSeek-V3") print("Loading tokenizer...") tok = AutoTokenizer.from_pretrained(model_name) print("Loading model...") m = AutoModelForCausalLM.from_pretrained( model_name, dtype=torch.float16 if torch.cuda.is_available() else torch.float32, device_map="auto", low_cpu_mem_usage=True ).eval() return m, tok async def start_load(): global model,tokenizer """在程序启动时,非阻塞地加载模型""" loop = asyncio.get_event_loop() # 使用线程池执行同步加载,避免阻塞事件循环 model, tokenizer = await loop.run_in_executor(None, load_model) print("✅ Model loaded during startup!") def shutdown_event(): """在应用关闭时清理资源""" global model, tokenizer if model is not None: del model if tokenizer is not None: del tokenizer if torch.cuda.is_available(): torch.cuda.empty_cache() print("👋 Cleaned up model and CUDA cache on shutdown.") app.add_event_handler("startup",start_load) app.add_event_handler("shutdown",shutdown_event) @app.get("/", response_class=HTMLResponse) async def home(): #挂载网页,连接前端 template = template_env.get_template("myapp.html") characters = database.get_all_characters() characters_json = json.dumps([{ "id": c["id"], "name": c["name"], "trait": c["trait"] } for c in characters], ensure_ascii=False) content = template.render(characters=characters, characters_json=characters_json) return HTMLResponse(content=content) @app.post("/chat") async def deepseek_chat(request: Request): data = await request.json() character_id = data.get("character_id") user_message = data.get("message") # 查询角色信息 conn = database.get_connection() cursor = conn.cursor(dictionary=True) cursor.execute("SELECT name, trait FROM characters WHERE id = %s", (character_id,)) character = cursor.fetchone() conn.close() if not character: return JSONResponse({"error": "角色不存在"}, status_code=404) # 构建系统提示词 system_prompt = f""" 你正在扮演 {character[&#39;name&#39;]}。 人物设定:{character[&#39;trait&#39;]} 请始终以这个角色的身份、语气和思维方式回答问题。 不要暴露你是 AI 的事实。 """.strip() # 👇 关键:使用本地模型进行推理 try: # 确保模型已加载 global model, tokenizer if model is None or tokenizer is None: return JSONResponse({"error": "模型尚未加载,请先启动模型"}, status_code=500) # 构造对话历史(必须使用 chat template) messages = [ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_message} ] # 使用 tokenizer.apply_chat_template 构造输入文本 input_text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True # 让模型知道要开始生成 assistant 回复 ) # Tokenize inputs = tokenizer(input_text, return_tensors="pt").to(model.device) # 生成参数 with torch.no_grad(): outputs = model.generate( **inputs, max_new_tokens=512, temperature=0.85, top_p=0.95, do_sample=True, repetition_penalty=1.1, eos_token_id=tokenizer.eos_token_id, pad_token_id=tokenizer.eos_token_id # 避免 decoder-only 模型 padding 报错 ) # 解码输出(去掉输入部分) full_response = tokenizer.decode(outputs[0], skip_special_tokens=False) # 提取 assistant 的回复内容 # 注意:apply_chat_template 已经添加了 <|assistant|> 标记 if "<|assistant|>" in full_response: reply = full_response.split("<|assistant|>")[-1].strip() else: reply = full_response[len(input_text):].strip() # 清理结尾可能的无关 token eot_token = "<|EOT|>" if eot_token in reply: reply = reply.split(eot_token)[0].strip() # 保存对话记录 database.save_conversation(character_id, user_message, reply) return JSONResponse({"reply": reply}) except Exception as e: import traceback error_msg = traceback.format_exc() # 更详细的错误日志 return JSONResponse({"error": f"推理失败: {str(e)}", "detail": error_msg}, status_code=500) # 非llama.cpp实现 if __name__ == "__main__": uvicorn.run("myapp:app", host="127.0.0.1", port=8000, reload=True) 将本地模型加载换为远程api请求
09-26
# E:\AI_System\web_ui\server.py import sys import os import time import logging import json import traceback import threading import platform import psutil import datetime from pathlib import Path from flask import Flask, jsonify, request, render_template from flask_socketio import SocketIO, emit from flask_limiter import Limiter from flask_limiter.util import get_remote_address from functools import wraps from concurrent.futures import ThreadPoolExecutor # ========== 配置系统 ========== class SystemConfig: def __init__(self): self.BASE_DIR = Path(__file__).resolve().parent.parent self.HOST = &#39;0.0.0.0&#39; # 改为0.0.0.0允许外部访问 self.PORT = 5000 self.LOG_LEVEL = &#39;DEBUG&#39; # 调试时使用DEBUG级别 self.SECRET_KEY = os.getenv(&#39;SECRET_KEY&#39;, &#39;your_secret_key_here&#39;) self.DEBUG = True self.USE_GPU = False self.DEFAULT_MODEL = &#39;gpt-3.5-turbo&#39; self.MAX_WORKERS = 4 # 线程池大小 # 目录配置 self.LOG_DIR = self.BASE_DIR / &#39;logs&#39; self.LOG_DIR.mkdir(parents=True, exist_ok=True) self.CONFIG_DIR = self.BASE_DIR / &#39;config&#39; self.CONFIG_DIR.mkdir(parents=True, exist_ok=True) self.AGENT_PATH = self.BASE_DIR / &#39;agent&#39; self.MODEL_CACHE_DIR = self.BASE_DIR / &#39;model_cache&#39; self.MODEL_CACHE_DIR.mkdir(parents=True, exist_ok=True) self.TEMPLATE_DIR = self.BASE_DIR / &#39;web_ui&#39; / &#39;templates&#39; # 显式指定模板目录 def __str__(self): return f"SystemConfig(HOST={self.HOST}, PORT={self.PORT})" config = SystemConfig() # ========== 全局协调器 ========== coordinator = None executor = ThreadPoolExecutor(max_workers=config.MAX_WORKERS) # 全局线程池 def register_coordinator(coord): """注册意识系统协调器""" global coordinator coordinator = coord if coordinator and hasattr(coordinator, &#39;connect_to_ui&#39;): coordinator.connect_to_ui(update_ui) def update_ui(event): """更新UI事件处理""" if &#39;socketio&#39; in globals(): socketio.emit(&#39;system_event&#39;, event) # ========== 初始化日志系统 ========== def setup_logger(): """配置全局日志系统""" logger = logging.getLogger(&#39;WebServer&#39;) logger.setLevel(getattr(logging, config.LOG_LEVEL.upper(), logging.DEBUG)) # 日志格式 log_formatter = logging.Formatter( &#39;%(asctime)s - %(name)s - %(levelname)s - %(message)s&#39;, datefmt=&#39;%Y-%m-%d %H:%M:%S&#39; ) # 文件日志处理器 (每天轮换,保留30天) file_handler = logging.handlers.TimedRotatingFileHandler( config.LOG_DIR / &#39;web_server.log&#39;, when=&#39;midnight&#39;, backupCount=30, encoding=&#39;utf-8&#39; ) file_handler.setFormatter(log_formatter) logger.addHandler(file_handler) # 控制台日志处理器 console_handler = logging.StreamHandler() console_handler.setFormatter(log_formatter) logger.addHandler(console_handler) return logger # 初始化日志 logger = setup_logger() # ========== 线程安全装饰器 ========== def synchronized(lock): """线程安全装饰器""" def decorator(func): @wraps(func) def wrapper(*args, **kwargs): with lock: return func(*args, **kwargs) return wrapper return decorator # ========== 系统初始化 ========== class SystemInitializer: """负责初始化系统核心组件""" def __init__(self): self.base_dir = Path(__file__).resolve().parent.parent self.ai_core = None self.hardware_manager = None self.life_scheduler = None self.ai_agent = None self.start_time = time.time() self.environment_manager = None self.life_lock = threading.Lock() # 生活系统线程锁 def initialize_system_paths(self): """初始化系统路径""" sys.path.insert(0, str(self.base_dir)) logger.info(f"项目根目录: {self.base_dir}") sub_dirs = [&#39;agent&#39;, &#39;core&#39;, &#39;utils&#39;, &#39;config&#39;, &#39;cognitive_arch&#39;, &#39;environment&#39;] for sub_dir in sub_dirs: full_path = self.base_dir / sub_dir if full_path.exists(): sys.path.insert(0, str(full_path)) logger.info(f"添加路径: {full_path}") else: logger.warning(f"目录不存在: {full_path} - 已跳过") def initialize_environment_manager(self): """初始化环境管理器""" try: # 环境管理器实现 class EnvironmentManager: def __init__(self, config): self.config = config self.state = { &#39;temperature&#39;: 22.5, &#39;humidity&#39;: 45.0, &#39;light_level&#39;: 75, &#39;objects&#39;: [], &#39;last_updated&#39;: datetime.datetime.now().isoformat() } self.healthy = True self.lock = threading.Lock() # 环境状态线程锁 @synchronized(threading.Lock()) def start(self): logger.info("环境管理器已启动") @synchronized(threading.Lock()) def get_state(self): # 更新模拟数据 self.state[&#39;temperature&#39;] = round(20 + 5 * (time.time() % 10) / 10, 1) self.state[&#39;humidity&#39;] = round(40 + 10 * (time.time() % 10) / 10, 1) self.state[&#39;light_level&#39;] = round(70 + 10 * (time.time() % 10) / 10, 1) self.state[&#39;last_updated&#39;] = datetime.datetime.now().isoformat() return self.state @synchronized(threading.Lock()) def execute_action(self, action, params): logger.info(f"执行环境动作: {action} 参数: {params}") if action == "adjust_temperature": self.state[&#39;temperature&#39;] = params.get(&#39;value&#39;, 22.0) return True elif action == "adjust_light": self.state[&#39;light_level&#39;] = params.get(&#39;level&#39;, 70) return True return False def is_healthy(self): return self.healthy env_config = {&#39;update_interval&#39;: 1.0, &#39;spatial&#39;: {&#39;grid_size&#39;: 1.0}} self.environment_manager = EnvironmentManager(env_config) self.environment_manager.start() logger.info("✅ 环境管理器初始化成功") return self.environment_manager except Exception as e: logger.error(f"❌ 环境管理器初始化失败: {str(e)}") logger.warning("⚠️ 环境交互功能将不可用") return None # 其他初始化方法保持不变,但添加线程安全装饰器... # initialize_ai_core, initialize_hardware_manager 等方法保持不变 @synchronized(lock=threading.Lock()) def initialize_life_scheduler(self): """初始化生活调度器(线程安全版本)""" # 实现保持不变... @synchronized(lock=threading.Lock()) def _update_life_status(self): """更新生活状态(线程安全版本)""" # 实现保持不变... @synchronized(lock=threading.Lock()) def initialize_ai_agent(self): """初始化AI智能体(线程安全版本)""" # 实现保持不变... def initialize_all(self): logger.info("=" * 50) logger.info("🚀 开始初始化AI系统") logger.info("=" * 50) self.initialize_system_paths() self.initialize_ai_core() self.initialize_hardware_manager() self.initialize_life_scheduler() self.initialize_ai_agent() self.initialize_environment_manager() self.start_evolution_monitor() logger.info("✅ 所有系统组件初始化完成") return { "ai_core": self.ai_core, "hardware_manager": self.hardware_manager, "life_scheduler": self.life_scheduler, "ai_agent": self.ai_agent, "environment_manager": self.environment_manager } # ========== Flask应用工厂 ========== def create_app(): app = Flask( __name__, template_folder=str(config.TEMPLATE_DIR), # 使用配置的模板目录 static_folder=&#39;static&#39;, static_url_path=&#39;/static&#39; ) app.secret_key = config.SECRET_KEY # 初始化限流器 limiter = Limiter( get_remote_address, app=app, default_limits=["200 per day", "50 per hour"], storage_uri="memory://" ) system_initializer = SystemInitializer() components = system_initializer.initialize_all() app.config[&#39;SYSTEM_COMPONENTS&#39;] = components app.config[&#39;START_TIME&#39;] = system_initializer.start_time app.config[&#39;BASE_DIR&#39;] = system_initializer.base_dir # 初始化SocketIO - 使用更高效的eventlet try: import eventlet eventlet.monkey_patch() async_mode = &#39;eventlet&#39; except ImportError: async_mode = &#39;threading&#39; logger.warning("eventlet未安装,使用threading模式,性能可能受影响") socketio = SocketIO( app, cors_allowed_origins="*", async_mode=async_mode, logger=logger, engineio_logger=logger ) app.config[&#39;SOCKETIO&#39;] = socketio # 注册路由 register_routes(app) register_error_handlers(app) # 注册限流器到应用 app.config[&#39;LIMITER&#39;] = limiter return app, socketio # ========== 环境交互路由 ========== def register_environment_routes(app): @app.route(&#39;/environment&#39;) def environment_view(): return render_template(&#39;environment_view.html&#39;) @app.route(&#39;/api/environment/state&#39;, methods=[&#39;GET&#39;]) @app.config[&#39;LIMITER&#39;].limit("10 per minute") def get_environment_state(): env_manager = app.config[&#39;SYSTEM_COMPONENTS&#39;].get(&#39;environment_manager&#39;) if not env_manager: return jsonify({"success": False, "error": "环境管理器未初始化"}), 503 try: state = env_manager.get_state() return jsonify(state) except Exception as e: app.logger.error(f"获取环境状态失败: {traceback.format_exc()}") return jsonify({"success": False, "error": str(e)}), 500 @app.route(&#39;/api/environment/action&#39;, methods=[&#39;POST&#39;]) @app.config[&#39;LIMITER&#39;].limit("5 per minute") def execute_environment_action(): env_manager = app.config[&#39;SYSTEM_COMPONENTS&#39;].get(&#39;environment_manager&#39;) if not env_manager: return jsonify({"success": False, "error": "环境管理器未初始化"}), 503 try: data = request.json action = data.get(&#39;action&#39;) params = data.get(&#39;params&#39;, {}) if not action: return jsonify({"success": False, "error": "缺少动作参数"}), 400 success = env_manager.execute_action(action, params) return jsonify({"success": success, "action": action}) except Exception as e: app.logger.error(f"执行环境动作失败: {traceback.format_exc()}") return jsonify({"success": False, "error": str(e)}), 500 # ========== 路由注册 ========== def register_routes(app): register_environment_routes(app) setup_environment_broadcast(app) # 健康检查路由 @app.route(&#39;/health&#39;) def health_check(): return jsonify({"status": "healthy", "timestamp": datetime.datetime.now().isoformat()}) # 系统状态路由 @app.route(&#39;/status&#39;) @app.config[&#39;LIMITER&#39;].exempt # 状态检查不限流 def status(): # 实现保持不变... # 核心系统路由 @app.route(&#39;/api/core/state&#39;) @app.config[&#39;LIMITER&#39;].limit("10 per minute") def get_core_state(): return jsonify(app.config[&#39;SYSTEM_COMPONENTS&#39;][&#39;ai_core&#39;].get_state()) # 生活系统路由 - 修复路由冲突 @app.route(&#39;/life/dashboard&#39;) # 修改路由避免冲突 def life_dashboard(): return render_template(&#39;life_dashboard.html&#39;) @app.route(&#39;/api/life/status&#39;) @app.config[&#39;LIMITER&#39;].limit("10 per minute") def get_life_status(): # 实现保持不变... # 聊天路由 - 添加异步处理 @app.route(&#39;/chat&#39;, methods=[&#39;POST&#39;]) @app.config[&#39;LIMITER&#39;].limit("30 per minute") def chat(): components = app.config[&#39;SYSTEM_COMPONENTS&#39;] if not components[&#39;ai_agent&#39;]: return jsonify({"error": "Agent未初始化"}), 503 try: data = request.get_json() user_input = data.get(&#39;message&#39;, &#39;&#39;) user_id = data.get(&#39;user_id&#39;, &#39;default&#39;) if not user_input: return jsonify({"error": "消息内容不能为空"}), 400 app.logger.info(f"聊天请求: 用户={user_id}, 内容长度={len(user_input)}") # 使用线程池异步处理 future = executor.submit(components[&#39;ai_agent&#39;].process_input, user_input, user_id) response = future.result(timeout=10) # 10秒超时 return jsonify({"response": response}) except TimeoutError: return jsonify({"error": "处理超时"}), 504 except Exception as e: app.logger.error(f"聊天处理失败: {traceback.format_exc()}") return jsonify({"error": "聊天处理失败", "details": str(e)}), 500 # 添加404处理 @app.route(&#39;/<path:path>&#39;) def catch_all(path): return jsonify({"error": "路由不存在", "path": path}), 404 # ========== WebSocket处理 ========== def setup_websocket_handlers(socketio): @socketio.on(&#39;connect&#39;) def handle_connect(): logger.info(&#39;客户端已连接&#39;) socketio.emit(&#39;system_status&#39;, {&#39;status&#39;: &#39;ready&#39;}) @socketio.on(&#39;disconnect&#39;) def handle_disconnect(): logger.info(&#39;客户端已断开连接&#39;) @socketio.on(&#39;user_message&#39;) def handle_user_message(data): user_id = data.get(&#39;user_id&#39;, &#39;guest&#39;) message = data.get(&#39;message&#39;, &#39;&#39;) logger.info(f"收到来自 {user_id} 的消息: {message}") # 使用线程池处理消息 def process_message(): try: # 如果有协调器,使用协调器处理 global coordinator if coordinator: return coordinator.process_message(message) else: return f"已收到您的消息: {message}" except Exception as e: logger.error(f"消息处理失败: {str(e)}") return "处理消息时出错" # 提交任务到线程池 future = executor.submit(process_message) try: response = future.result(timeout=10) # 10秒超时 socketio.emit(&#39;agent_response&#39;, { &#39;user_id&#39;: user_id, &#39;response&#39;: response }) except TimeoutError: socketio.emit(&#39;agent_response&#39;, { &#39;user_id&#39;: user_id, &#39;response&#39;: "处理超时,请重试" }) # ========== 生产环境启动器 ========== def run_production_server(app): """生产环境部署配置""" from waitress import serve # 添加生产环境日志轮转 handler = logging.handlers.RotatingFileHandler( config.LOG_DIR / &#39;production.log&#39;, maxBytes=10 * 1024 * 1024, # 10MB backupCount=5, encoding=&#39;utf-8&#39; ) handler.setLevel(logging.INFO) handler.setFormatter(logging.Formatter( &#39;%(asctime)s - %(name)s - %(levelname)s - %(message)s&#39;, datefmt=&#39;%Y-%m-%d %H:%M:%S&#39; )) app.logger.addHandler(handler) logger.info(f"🚀 生产服务器启动: http://{config.HOST}:{config.PORT}") logger.warning("⚠️ 当前运行在生产模式 (Waitress WSGI服务器)") serve(app, host=config.HOST, port=config.PORT, threads=8) # ========== 主程序入口 ========== if __name__ == &#39;__main__&#39;: try: app, socketio = create_app() # 设置WebSocket处理器 setup_websocket_handlers(socketio) # 根据配置选择运行模式 if config.DEBUG: # 开发模式 logger.info(f"开发服务器运行在 http://{config.HOST}:{config.PORT}") socketio.run( app, host=config.HOST, port=config.PORT, debug=True, use_reloader=False ) else: # 生产模式 run_production_server(app) except KeyboardInterrupt: logger.info("服务器关闭") executor.shutdown(wait=False) except Exception as e: logger.critical(f"服务器启动失败: {str(e)}") logger.error(traceback.format_exc()) executor.shutdown(wait=False) sys.exit(1) 大哥 这是你刚刚写的啊 好坑啊 能修复好不?
08-12
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值