答案 0 :(得分:1)
参考:
与Future关联的可调用对象等待时可能会发生死锁 在另一个Future的结果上。
那里的两个例子显示了死锁是如何发生的。尝试将.submit()
替换为.map()
,然后进行其他必要的更改。`
内幕:
根据Python的python3.6/concurrent/futures/thread.py
模块(在系统中搜索该文件),类ThreadPoolExecutor
实际上使用queue.Queue()
(请参见第107行)来实现python线程并使用基本的{{1 }}(请参见第110行)以锁定线程。
说明:
如果对您来说“线程安全”是指程序中的多个线程,每个线程都试图访问内存中的通用数据结构或位置,那么您应该知道threading.Lock()
仅允许一个线程访问线程。一次在内存中使用通用数据结构或位置; concurrent.futures.ThreadPoolExecutor
原语用来管理它。当一个线程中的一个函数需要等待另一个线程中的结果时,就会发生死锁,并且您的代码将无法工作。这应该避免。
答案 1 :(得分:0)
from concurrent.futures import ThreadPoolExecutor, as_completed
import time
resultDict = {0: [], 1: [], 2: [], 3: [], 4: []}
resultDict1 = {0: [], 1: [], 2: [], 3: [], 4: []}
def appendResult(a, b):
result = a ** b
resultDict[result % 5].append(result)
time.sleep(1)
def appendResult1(a, b):
result = a ** b
resultDict1[result % 5].append(result)
time.sleep(1)
startTime = time.time()
processes = []
with ThreadPoolExecutor(max_workers=12) as executor:
for i in range(100):
processes.append(executor.submit(appendResult, i, 2))
for task in as_completed(processes):
task.result()
print("Cost", time.time() - startTime, "s")
startTime = time.time()
for i in range(100):
appendResult1(i, 2)
print("Cost", time.time() - startTime, "s")
是的,它是线程安全的。因此resultDict和resultDict1在上述代码的末尾将是相同的。