我是一个在Python中与多处理哲学作斗争的比特人。为了测试我的知识,我想到了一个计算整数素数分解的多处理程序。如下所示。将整数放入队列中。然后我有一个函数,它可以出列并搜索它的(素数(除数。如果找到一个,互补整数就会放回队列。我怎样才能做到这一点。目前我有这个:
import multiprocessing as mp
def f(queue, decomp):
x = queue.get()
prime = True
for i in range(2, x):
if (x % i) == 0:
decomp.put(i)
prime = False
queue.put(x // i)
break
if prime:
decomp.put(x)
class Num:
def __init__(self, n):
self.queue = mp.Queue()
self.queue.put(n)
self.decomposition = mp.Queue()
def run(self):
with mp.Pool(4) as pool:
pool.apply_async(f, (self.queue, self.decomposition))
它提高了
RuntimeError: Queue objects should only be shared between processes through inheritance
做这个的标准方法是什么?(我知道可能有更好的方法来给出素数分解(
为了使用multiprocessing.Queue
,您需要将其作为创建点传递给每个子进程(这样它们就可以"继承"(,而不是将它们作为参数传递给apply_async
。如果你在Linux上,你可以通过在全局范围内声明它们来实现这一点,而不是在Num
类上声明为无形变量——它们将通过分叉过程继承:
import multiprocessing as mp
queue = mp.Queue()
decomposition = mp.Queue()
def f():
x = queue.get()
prime = True
for i in range(2, x):
if (x % i) == 0:
decomposition.put(i)
prime = False
queue.put(x // i)
break
if prime:
decomposition.put(x)
class Num:
def __init__(self, n):
queue.put(n)
def run(self):
with mp.Pool(4) as pool:
pool.apply(f)
在Windows上,它更为复杂,因为它不支持分叉。相反,您必须在Pool
构造函数上使用init
和initargs
关键字参数来将队列传递给子进程,然后在您提供的初始化器函数中将它们声明为全局变量。这将把队列放在工作进程的全局范围内,允许您在传递给所有Pool
方法(map
/map_async
、apply
/apply_async
(的函数中使用它们。
import multiprocessing as mp
def f():
x = queue.get()
prime = True
for i in range(2, x):
if (x % i) == 0:
decomp.put(i)
prime = False
queue.put(x // i)
break
if prime:
decomp.put(x)
def init(q, d):
# Put the queues in the global scope of the worker processes
global queue, decomp
queue = q
decomp = d
class Num:
def __init__(self, n):
self.queue = mp.Queue()
self.queue.put(n)
self.decomposition = mp.Queue()
def run(self):
with mp.Pool(4, initializer=init, initargs=(self.queue, self.decomposition)) as pool:
pool.apply(f)