在具有多线程(使用 concurrent.futures)的 Python 中,List-append 会导致偏移行



我是一个新手python爱好者,已经开始尝试使用concurrent.futures进行多线程处理。

每个单独的线程都应该分析一个 HTML 文件,然后将某些项目附加到列表中。完成所有线程后,生成的列表将写入 CSV 文件。

令人惊讶的结果是,行的某些部分似乎在列表中偏移了 1 行,例如:

预期成果:

caseList = [
[a1, a2, a3],
[b1, b2, b3],
[c1, c2, c3],
[d1, d2, d3],
]

实际结果:

caseList = [
[a1, a2, a3],
[b1, a2, a3],
[c1, b2, b3],
[d1, c2, c3]
]

其中字母正好代表一个应该由一个线程分析的 HTML 文件。 我无法确切地确定它在哪里更改,但它开始时是正确的,但随后某些行部分包含应属于上一行的项目。

我已经阅读了有关竞争条件和锁定的信息,但也阅读了list.append应该是线程安全的评论。所以不完全确定这里在起作用。

这是我的代码:

caseList = []
with concurrent.futures.ThreadPoolExecutor() as executor:
results = [executor.submit(searchCase, filename, pattern) for filename in logContents]
for f in concurrent.futures.as_completed(results):
caseList.append(f.result())
print(f.result())

我在这里明显做错了什么吗?

对此问题的响应位于使用 ThreadPoolExecutor 时避免竞争条件

不应期望从生成器返回有序结果 for 循环:

for f in concurrent.futures.as_completed(results):

存在以控制由 concurrent.futures.as_completed(结果( 创建的生成器。但是,结果是可用的产量。由于它是异步执行,因此结果将产生无序的。

您可以在 current.future 文档中看到此说明:

concurrent.futures.as_completed(fs, timeout=none(

返回 fs 给出的未来实例(可能由不同的执行器实例创建(的迭代器,该迭代器在完成时生成期货(已完成或取消的期货(。fs 给出的任何重复期货都将返回一次。在调用as_completed((之前完成的任何期货都将首先产生。返回的迭代器将引发 concurrent.futures.TimeoutError 如果调用next((,并且结果在原始调用 as_completed(( 的超时秒数后不可用。超时可以是整数或浮点数。如果未指定超时或"无",则等待时间没有限制。

希望这有帮助

最新更新