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

如何将线程内调用函数的返回值保存到循环外的公共列表中

多线程收集process_folders返回值的实现方案

Python标准库的threading.Thread默认不会返回目标函数的执行结果,你可以用以下3种常见方案实现结果收集:


方案1:传入可变公共容器收集结果

列表、字典这类可变对象可以直接在线程间共享,CPython中列表的append操作是原子性的,简单场景下无需额外加锁:

import time
import glob
from threading import Thread

def compare_two_images(image1, image2):  
    # 你的比对逻辑
    return "相似图片地址" if "相似判断条件" else None

def process_folders(path_to_folder, result_list):
    print("Current Folder: " + path_to_folder)
    start_time = time.time()
    # 修正原代码笔误:原参数是path_to_folder,不是folder
    input_arr = glob.glob(path_to_folder+'/*')
    res = [compare_two_images(input_arr[i], input_arr[i + 1]) for i in range(len(input_arr) - 1)]
    print("Folder completed with " + str(time.time() - start_time))
    # 把结果加入公共列表,不需要return
    result_list.append({
        "folder_path": path_to_folder,
        "compare_result": res
    })

# 公共结果列表
all_results = []
threads = []
# 你的子文件夹列表
folder_with_subfolders = ["./test1", "./test2"]
for folder in folder_with_subfolders:
    # 把公共列表作为参数传入线程
    threads.append(Thread(target=process_folders, args=(folder, all_results)))
    threads[-1].start()

for thread in threads:
    thread.join()

# 所有线程执行完成后,all_results里就有全部结果了
print(all_results)

方案2:使用concurrent.futures.ThreadPoolExecutor(更推荐)

这个高阶库会自动管理线程,且可以直接获取每个线程的返回值,不需要手动维护公共容器:

import time
import glob
from concurrent.futures import ThreadPoolExecutor

def compare_two_images(image1, image2):  
    return "相似图片地址" if "相似判断条件" else None

def process_folders(path_to_folder):
    print("Current Folder: " + path_to_folder)
    start_time = time.time()
    input_arr = glob.glob(path_to_folder+'/*')
    res = [compare_two_images(input_arr[i], input_arr[i + 1]) for i in range(len(input_arr) - 1)]
    print("Folder completed with " + str(time.time() - start_time))
    # 直接返回结果即可
    return {
        "folder_path": path_to_folder,
        "compare_result": res
    }

folder_with_subfolders = ["./test1", "./test2"]
all_results = []
#  max_workers设置最大同时执行的线程数,可根据硬件调整
with ThreadPoolExecutor(max_workers=4) as executor:
    # 提交所有任务,得到future对象列表
    futures = [executor.submit(process_folders, folder) for folder in folder_with_subfolders]
    # 逐个获取返回值
    for future in futures:
        all_results.append(future.result())

print(all_results)

方案3:自定义Thread子类存储返回值

重写Thread的run方法,把返回值存到实例属性中,线程执行结束后直接读取属性即可:

import time
import glob
from threading import Thread

def compare_two_images(image1, image2):  
    return "相似图片地址" if "相似判断条件" else None

# 自定义Thread子类
class ResultThread(Thread):
    def run(self):
        self.result = None
        if self._target is not None:
            self.result = self._target(*self._args, **self._kwargs)

def process_folders(path_to_folder):
    print("Current Folder: " + path_to_folder)
    start_time = time.time()
    input_arr = glob.glob(path_to_folder+'/*')
    res = [compare_two_images(input_arr[i], input_arr[i + 1]) for i in range(len(input_arr) - 1)]
    print("Folder completed with " + str(time.time() - start_time))
    return res

folder_with_subfolders = ["./test1", "./test2"]
threads = []
for folder in folder_with_subfolders:
    threads.append(ResultThread(target=process_folders, args=(folder,)))
    threads[-1].start()

all_results = []
for thread in threads:
    thread.join()
    # 读取线程实例的result属性拿到返回值
    all_results.append(thread.result)

print(all_results)

注意事项

如果你的图片比对逻辑是CPU密集型运算,Python多线程受GIL(全局解释器锁)限制无法真正并行,不会有明显提速,建议换成多进程实现,上述方案换成multiprocessing相关API即可通用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 02:51:01