You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 22:43:00