python多线程管理

33 阅读2分钟
import threading
import time
import random
from typing import List, Callable, Dict

class DynamicThreadManager:
    def __init__(self):
        self.threads: Dict[int, threading.Thread] = {}  # 存储线程ID和线程对象
        self.task_counter = 0  # 任务计数器,用于生成唯一ID
        self.lock = threading.Lock()  # 线程安全锁
        self.running = True  # 管理器运行状态
        
    def create_task(self, task_func: Callable, *args, **kwargs) -> int:
        """创建并启动一个新任务线程"""
        with self.lock:
            self.task_counter += 1
            task_id = self.task_counter
        
        # 包装任务函数,添加线程管理逻辑
        def wrapped_task():
            try:
                task_func(*args, **kwargs)
            except Exception as e:
                print(f"任务 {task_id} 执行出错: {str(e)}")
            finally:
                with self.lock:
                    if task_id in self.threads:
                        del self.threads[task_id]
        
        thread = threading.Thread(target=wrapped_task, name=f"Task-{task_id}")
        thread.daemon = True  # 设置为守护线程,主程序退出时自动结束
        
        with self.lock:
            self.threads[task_id] = thread
        
        thread.start()
        print(f"已启动任务 {task_id}")
        return task_id
    
    def stop_task(self, task_id: int) -> bool:
        """停止指定ID的任务线程"""
        with self.lock:
            if task_id not in self.threads:
                return False
                
            thread = self.threads[task_id]
            
            # 注意:Python没有直接终止线程的安全方法,这里只是标记并让线程自然结束
            # 实际应用中需要任务函数支持优雅退出
            print(f"请求停止任务 {task_id} (请确保任务支持优雅退出)")
            del self.threads[task_id]
            return True
    
    def stop_all_tasks(self) -> None:
        """停止所有任务线程"""
        with self.lock:
            task_ids = list(self.threads.keys())
        
        for task_id in task_ids:
            self.stop_task(task_id)
        
        print("所有任务已请求停止")
    
    def get_active_tasks(self) -> List[int]:
        """获取当前活跃的任务ID列表"""
        with self.lock:
            return list(self.threads.keys())
    
    def shutdown(self) -> None:
        """关闭管理器,停止所有任务"""
        self.running = False
        self.stop_all_tasks()


# 示例任务函数
def sample_task(task_name: str, duration: int = None):
    """示例任务:随机运行一段时间后结束"""
    print(f"任务 {task_name} 开始执行")
    start_time = time.time()
    
    # 如果未指定持续时间,则随机1-10秒
    if duration is None:
        duration = random.randint(1, 10)
    
    # 模拟任务执行,定期检查是否需要退出
    while time.time() - start_time < duration:
        print(f"任务 {task_name} 正在运行...")
        time.sleep(1)
    
    print(f"任务 {task_name} 执行完成")


if __name__ == "__main__":
    # 创建线程管理器
    manager = DynamicThreadManager()
    
    try:
        # 初始启动3个不同的任务
        print("=== 启动初始任务 ===")
        task1 = manager.create_task(sample_task, "数据处理", 8)
        task2 = manager.create_task(sample_task, "文件下载", 5)
        task3 = manager.create_task(sample_task, "网络请求", 12)
        
        print(f"当前活跃任务: {manager.get_active_tasks()}")
        
        # 等待3秒后添加新任务
        time.sleep(3)
        print("\n=== 添加新任务 ===")
        task4 = manager.create_task(sample_task, "日志分析", 6)
        print(f"当前活跃任务: {manager.get_active_tasks()}")
        
        # 等待2秒后停止一个任务
        time.sleep(2)
        print("\n=== 停止一个任务 ===")
        manager.stop_task(task2)
        print(f"当前活跃任务: {manager.get_active_tasks()}")
        
        # 等待所有任务完成
        while manager.get_active_tasks():
            time.sleep(1)
        
        print("\n所有任务已完成")
    
    except KeyboardInterrupt:
        print("\n用户中断,正在停止所有任务...")
        manager.shutdown()