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

Python实现线程内重试函数n次后退出时日志重复打印问题排查

问题原因分析

你的代码重复打印退出日志的核心问题是递归调用后没有终止当前函数栈的执行,同时混用了循环和递归两套重试逻辑:

  • 每次捕获异常后你调用了_manage_thread(thread_restart_count)进入下一层递归,但是递归执行完返回后,当前层级的函数还会继续往下走,执行while循环内的打印退出日志的代码,所以有多少层活跃递归,就会多打印多少次退出日志。
  • 你同时用了while循环和递归实现重试,逻辑完全冗余,两种逻辑随便选一种就足够实现需求。
修正方案

方案1:仅用循环实现(更推荐,无递归栈溢出风险)

import time
from threading import Thread

# 可自行调整最大重试次数
MAX_THREAD_RESTART_COUNT = 3

def run_thread_n_times(self, func, **kwargs):
    def _manage_thread():
        thread_restart_count = 0
        while thread_restart_count < MAX_THREAD_RESTART_COUNT:
            try:
                time.sleep(3)
                # 测试用异常,实际使用时删除即可
                raise Exception("fuck")
                func()
                # 函数执行成功直接退出
                return
            except Exception:
                thread_restart_count += 1
                print(f"Thread crashed for {thread_restart_count} time(s)")
        # 重试次数用尽后打印退出日志
        print(f"Thread crashed more than {MAX_THREAD_RESTART_COUNT} times, exiting...")

    name = self.name if "name" not in kwargs else kwargs['name']
    print(f"{name}: thread started")
    thread = Thread(target=_manage_thread, name=name, args=())
    thread.start()

方案2:仅用递归实现

import time
from threading import Thread

MAX_THREAD_RESTART_COUNT = 3

def run_thread_n_times(self, func, **kwargs):
    def _manage_thread(thread_restart_count):
        # 先判断是否超出重试次数
        if thread_restart_count >= MAX_THREAD_RESTART_COUNT:
            print(f"Thread crashed more than {MAX_THREAD_RESTART_COUNT} times, exiting...")
            return
        try:
            time.sleep(3)
            # 测试用异常,实际使用时删除即可
            raise Exception("fuck")
            func()
            return
        except Exception:
            thread_restart_count += 1
            print(f"Thread crashed for {thread_restart_count} time(s)")
            _manage_thread(thread_restart_count)
            
    name = self.name if "name" not in kwargs else kwargs['name']
    print(f"{name}: thread started")
    thread = Thread(target=_manage_thread, name=name, args=(0,))
    thread.start()

两种方案运行后均可输出你预期的结果,不会重复打印退出日志。

内容的提问来源于stack exchange,提问作者toing_toing

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 16:45:03