【发布时间】:2019-06-27 22:23:56
【问题描述】:
我正在尝试减少读取大约 100,000 个条目的数据库的处理时间,但我需要以特定方式对它们进行格式化,为了做到这一点,我尝试使用 python 的 multiprocessing.map 函数完美,除了我似乎无法获得任何形式的队列引用来处理它们。
我一直在使用来自Filling a queue and managing multiprocessing in python 的信息来指导我跨多个进程使用队列,并使用Using a global variable with a thread 来指导我跨线程使用全局变量。我已经让软件工作了,但是当我在运行进程后检查列表/队列/字典/地图长度时,它总是返回零
我写了一个简单的例子来说明我的意思:
您必须将脚本作为文件运行,map 的 initialize 函数在解释器中不起作用。
from multiprocessing import Pool
from collections import deque
global_q = deque()
def my_init(q):
global global_q
global_q = q
q.append("Hello world")
def map_fn(i):
global global_q
global_q.append(i)
if __name__ == "__main__":
with Pool(3, my_init, (global_q,)) as pool:
pool.map(map_fn, range(3))
for p in range(len(global_q)):
print(global_q.pop())
理论上,当我使用 pool 函数将队列对象引用从主线程传递给工作线程,然后使用给定函数初始化该线程的全局变量时,当我从map 函数之后,该对象引用仍应指向原始队列对象引用(长话短说,所有内容都应在同一个队列中结束,因为它们都指向内存中的同一位置)。
所以,我希望:
Hello World
Hello World
Hello World
1
2
3
当然,1, 2, 3 的顺序是任意的,但您会在输出中看到''。
当我将对象引用传递给pool 函数时,为什么没有任何反应?
【问题讨论】:
-
deque与Queue不同,多进程与多线程不同 — 你知道这一点,对吗?每个进程都在自己的“内存空间”中运行,这使得它们无法直接共享全局变量。可以使用multiprocessing.managers.SyncManager间接为 some 类型创建代理,以允许共享记录的类型。不幸的是,deque不在其中,但您可以自己实现一个。 -
这是我正在谈论的概念,或者在谈论在不同线程上初始化全局变量时希望展示的概念,我只关心这样做,因为我已经看到 python 中的每个进程都有它自己的环境/解释器,所以理论上我想如果我将原始对象的引用传递给新的解释器,那么我应该能够将其全局变量重新初始化为旧的,至少这是我的猜测
-
iggy12345:我可以理解您是如何获得这种印象的,但事实是您不能将引用传递给其他进程,因为该对象位于另一个他们无法访问的内存空间中。请参阅我刚刚发布的答案,该答案显示了如何使用多处理
Manager完成您想要的事情。
标签: python multiprocessing deque