【发布时间】:2020-12-05 00:28:08
【问题描述】:
我正在尝试使用forkserver,但在工作进程中遇到了NameError: name 'xxx' is not defined。
我使用的是 Python 3.6.4,但文档应该是相同的,来自 https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods 它说:
fork 服务器进程是单线程的,因此使用 os.fork() 是安全的。 不会继承不必要的资源。
另外,它说:
比pickle/unpickle更好继承
在使用 spawn 或 forkserver 启动方法时,来自多处理的许多类型需要是可挑选的,以便子进程可以使用它们。但是,通常应该避免使用管道或队列将共享对象发送到其他进程。 相反,您应该安排程序,以便需要访问在其他地方创建的共享资源的进程可以从祖先进程继承它。
显然,我的工作进程需要处理的关键对象没有被服务器进程继承然后传递给工作人员,为什么会发生这种情况?我想知道 forkserver 进程到底从父进程继承了什么?
我的代码如下所示:
import multiprocessing
import (a bunch of other modules)
def worker_func(nameList):
global largeObject
for item in nameList:
# get some info from largeObject using item as index
# do some calculation
return [item, info]
if __name__ == '__main__':
result = []
largeObject # This is my large object, it's read-only and no modification will be made to it.
nameList # Here is a list variable that I will need to get info for each item in it from the largeObject
ctx_in_main = multiprocessing.get_context('forkserver')
print('Start parallel, using forking/spawning/?:', ctx_in_main.get_context())
cores = ctx_in_main.cpu_count()
with ctx_in_main.Pool(processes=4) as pool:
for x in pool.imap_unordered(worker_func, nameList):
result.append(x)
谢谢!
最好的,
【问题讨论】:
-
我尝试将
nameList拆分为 4 个块并在imap_unordered中使用 zip([largeObject]*4, nameLis_splittedt) 并稍后在worker_func()中解开它,这样它确实得到了 @987654328 @ 进入工人,但它变得超级慢。我猜这是由于largeObject的大小。 -
在工作函数定义之前初始化大对象。
-
@AnmolSinghJaggi 你能解释一下如何初始化吗?
largeObject这是一个NetworkX对象,它来自__main__中的一系列先前计算,其中涉及读取大熊猫df 和其他内存消耗操作。
标签: python multiprocessing global multiprocess