类中循环创建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
相关产品推荐
相关产品推荐

