threading.Lock()失效排查:路由设备多线程执行日志写入异常
解决方案
核心问题分析
- 原代码锁的位置完全错误:锁在了线程创建和启动阶段,根本没控制函数执行时的日志写入或资源竞争,起不到任何作用。
- 全局
thread_list会累积所有线程,导致后续join操作等待无关线程,引发逻辑混乱。 - 你的核心需求是同一conn和host对应的所有函数执行完成后,再处理下一组conn/host,同时要解决日志写入的并发冲突。
正确代码修改方案
1. 拆分锁的作用范围
给日志写入操作单独加锁,而非全局包裹线程逻辑,既解决文件写入竞争,又保留多线程的执行效率。
2. 修正线程管理逻辑
为每个conn/host单独维护线程列表,避免全局列表的干扰,确保当前主机的所有任务执行完毕后再处理下一台设备。
修改后的代码示例:
import threading from datetime import datetime # 全局日志锁,仅用于控制文件写入操作 log_lock = threading.Lock() def looper(): while not thread_pool.empty(): conn = thread_pool.get() host = ip_pool.get() current_threads = [] # 为当前主机创建所有任务线程 for func in function_list: t = threading.Thread(target=func, args=(conn, host, log_lock), daemon=True) t.start() current_threads.append(t) # 等待当前主机的所有线程执行完毕,再处理下一台 for t in current_threads: t.join() print(f"线程{t.__repr__()}执行完成")
3. 函数内部的日志加锁
在每个路由器操作函数中,用传入的log_lock保护日志写入环节:
def router_command_func(conn, host, log_lock): # 执行路由器命令逻辑 command_result = conn.run_some_command() # 写入日志时加锁,避免多线程同时写文件 with log_lock: with open(f"{host}_log.txt", "a", encoding="utf-8") as f: f.write(f"{datetime.now()}: {command_result}\n")
常见坑点规避
- 不要用全局锁包裹整个函数执行:这会把所有线程变成串行,完全失去多线程意义,还可能因锁未释放导致程序冻结。
- 禁止使用全局线程列表:每个主机的线程单独管理,防止
join操作等待无关线程。 - 优先用
with lock:语法:自动处理锁的获取和释放,避免手动acquire后忘记release引发的死锁。
内容的提问来源于stack exchange,提问作者hfakoor222
相关产品推荐
相关产品推荐

