首页 > 解决方案 > 为什么我在这个多线程中总是以空白数据结束

问题描述

我使用 ThreadPoolExector 复制/修改了一个类,以及一个名为 add_task 的提交函数,从而将函数和 args 提交到池中,但是有时它从池中执行的函数有空白数据。我怀疑这是因为我在提交后正在清除列表,但我不知道如何修复它。发送函数调用不会复制变量,对吗?它只是传递一个参考?因此,如果在函数提交和线程被调用 dictlist.clear() 之间的时间,线程不再具有提交给 POST 的值?那是比赛条件吗?我该如何解决?我的印象是 ThreadPoolExecution (和队列,因为我也尝试过)确实锁定了自己,但也许我在这里遗漏了一些重要的东西。

这是调用类函数的代码:

with open(xmfp + "pythoncsvSector.csv", "r", encoding="utf-8", newline='') as sectorcsv:
    reader = csv.DictReader(sectorcsv, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) # fieldnames parameter skipped so it knows first row is headers
    for row in reader:
        dictlist.append(row)
        counter += 1
        if counter == 100:
            pool.add_task(submitToSite, dictlist, "Sector")
            dictlist.clear()
            counter = 0

这是课程:

class ThreadExecutor:
    def __init__(self, max_workers):
        self.executor = ThreadPoolExecutor(max_workers=max_workers)

    def add_task(self, fn, *args, **kwargs):
        try:
            future = self.executor.submit(fn, *args, **kwargs)
        except Exception as e:
            print(e)
        else:
            return future

我正在调用的函数执行 POST 请求并将响应文本和状态代码写入文件。

这是完整的代码:https ://pastebin.com/Qu6cYSnE

标签: python-3.xmultithreading

解决方案


变量在线程之间共享。在这种情况下,如果您要更改原始列表,则可以将列表的副本提交给工作线程:

pool.add_task(submitToSite, dictlist[:], "Sector")

或者您可以分配给dictlist一个新列表,而不是使用以下命令就地清除它dictlist.clear()

dictlist = []

推荐阅读