我是一个新手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(( 的超时秒数后不可用。超时可以是整数或浮点数。如果未指定超时或"无",则等待时间没有限制。
希望这有帮助