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

类中循环创建threading.Thread多线程无法存储正确参数求助

问题原因与修复方案

问题根源

你遇到的问题是因为字典是可变对象——在循环创建线程时,你一直对同一个kwargs字典执行update操作,所有线程对象实际上引用的是同一个字典实例。当线程启动时,字典里的targets和thread_idx已经被最后一次循环覆盖,所以所有线程都会使用最后一个切片的数据。

修复方法

每次循环时创建一个独立的字典副本,让每个线程持有自己的参数字典,避免共享同一个对象:

修改Threader类的create方法中的循环部分:

for idx, sublist in enumerate(targets_splitted):            
    # 基于传入的kwargs创建新字典副本,避免所有线程共享同一对象
    thread_kwargs = kwargs.copy()
    thread_kwargs.update({'targets': sublist, 'thread_idx': idx})
    thread_ = threading.Thread(target=self.function, kwargs=thread_kwargs)
    self.threads.append(thread_)
    print(f'Thread {idx} created. Kwargs: {thread_kwargs}')

额外优化:修复可变默认参数隐患

Python中可变默认参数(比如kwargs: dict = {})会在函数定义时创建一次,多次调用create方法可能导致参数残留。建议修改create方法的参数定义:

def create(self, targets: list, kwargs: dict | None = None):
    # 初始化空字典,避免可变默认参数的副作用
    kwargs = kwargs or {}
    # 后续原有逻辑不变

完整修改后的create方法

def create(self, targets: list, kwargs: dict | None = None):
    """
    Creates multiple threading.Thread objects

    :param targets: list of targets to be splitted between the threads.
    :param kwargs: kwargs to be passed to threading.Thread object
    """
    kwargs = kwargs or {}
    splits = int(len(targets)//self.n_threads) + 1
    targets_splitted: list[SubjectType] = []
    for sublist in list_chunks(targets, size=splits):
        targets_splitted.append(sublist)        

    self.threads: list[threading.Thread] = []
    for idx, sublist in enumerate(targets_splitted):            
        thread_kwargs = kwargs.copy()
        thread_kwargs.update({'targets': sublist, 'thread_idx': idx})
        thread_ = threading.Thread(target=self.function, kwargs=thread_kwargs)
        self.threads.append(thread_)
        print(f'Thread {idx} created. Kwargs: {thread_kwargs}')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 10:02:41