我有Django项目。如果我创建包含 Pool()对象的包变量,并尝试从Django视图(以并行方式运行)使用该池,那么这样的线程安全吗?有没有其他方法可以做到这一点?
from multiprocessing import Pool
general_executor_pool = Pool()
答案 0 :(得分:4)
我通过谷歌发现了这个问题,因为我问的是同一个问题。有趣的是,我可以说它不是,因为我最近调试了一个遭受竞争条件的软件。这是怎么回事:
我喜欢通过多处理模块进行跟踪,看看它是否是设计上的非线程安全的,或者是从知道的人那里得到答案。有趣的是,至少,我亲眼目睹了它不是。
答案 1 :(得分:0)
为了记录,我不得不检查这个,似乎 multiprocessing.pool.Pool 确实是线程安全的。 以下代码不会触发 AssertionError(使用 Python 3.6.9 测试):
import random
import time
import multiprocessing.pool
from threading import Thread
pool = multiprocessing.pool.Pool()
def return_value(value):
time.sleep(random.random())
return value
count = 100
def call_return_value():
counter_start = random.randint(0, 100)
result = list(range(counter_start, counter_start + count))
pool_result = pool.imap_unordered(return_value, range(counter_start, counter_start + count), chunksize=1)
pool_result = list(pool_result)
assert set(pool_result) == set(result)
tl = [Thread(target=call_return_value) for _ in range(24)]
for t in tl:
t.start()
基本上,这段代码启动了一个进程池,并启动了 24 个线程,通过这个池调用 return_value
函数。此函数在等待随机延迟(0 到 1 秒之间)后返回值。
当然,pool_result 不再排序,但它包含正确的元素集,这对所有线程都是正确的:值不会混合。