concurrent.futures.map是线程安全的吗?

时间:2019-03-19 20:58:41

标签: python-3.x concurrent.futures

2 个答案:

答案 0 :(得分:1)

参考:

根据ThreadPoolExecutor

  

与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在上述代码的末尾将是相同的。