我有一个Django项目。如果我创建一个包含Pool()对象的变量,并尝试从Django视图中使用该池(以并行方式运行),这种方式是否是线程安全的?还有其他方法可以实现吗?
from multiprocessing import Pool
general_executor_pool = Pool()
值得一提的是,我不得不检查这个问题,而 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不再有序,但它包含了正确的元素集合,对于所有线程都是如此:值不会混合。