我一直在使用multiprocessing
软件包来加速某些地理处理(GIS/arcpy
)任务,这些任务是多余的,需要对2000多个相似的几何体进行相同的处理。为什么我们必须显式传递常量到多处理函数中?
分离效果很好,但我的“工作人员”功能相当长且复杂,因为从头到尾的任务本身都很复杂。我很想分开更多的步骤,但是我无法将信息传递给/从worker函数,因为出于某种原因,需要明确传入多处理使用的worker函数。
这意味着我无法在if __name__ == '__main__'
正文中定义常量,然后在辅助函数中使用它们。这也意味着我的工作函数参数列表变得非常长 - 这是超级丑陋,因为尝试使用多个参数也需要创建一个帮助器“星号”函数,然后itertools
将它们重新解压缩(第二秒回答于this question)。
我在下面创建了一个简单的例子,演示了我在说什么。是否有任何解决方法 - 我应该使用的不同方法 - 或者至少可以解释一下为什么这是它的方式?
注意:我在Windows Server 2008 R2 Enterprise x64上运行此操作。
编辑:我似乎没有把我的问题弄清楚。我并不关心pool.map
如何只接受一个参数(尽管它很烦人),而是我不明白为什么在if __name__ == '__main__'
以外定义的函数的作用域如果用作多处理函数时不能访问该块内定义的东西 - 除非你明确地将它作为参数传递,这是令人讨厌的。
import os
import multiprocessing
import itertools
def loop_function(word):
file_name = os.path.join(root_dir, word + '.txt')
with open(file_name, "w") as text_file:
text_file.write(word + " food")
def nonloop_function(word, root_dir): # <------ PROBLEM
file_name = os.path.join(root_dir, word + '.txt')
with open(file_name, "w") as text_file:
text_file.write(word + " food")
def nonloop_star(arg_package):
return nonloop_function(*arg_package)
# Serial version
#
# if __name__ == '__main__':
# root_dir = 'C:\\hbrowning'
# word_list = ['dog', 'cat', 'llama', 'yeti', 'parakeet', 'dolphin']
# for word in word_list:
# loop_function(word)
#
## --------------------------------------------
# Multiprocessing version
if __name__ == '__main__':
root_dir = 'C:\\hbrowning'
word_list = ['dog', 'cat', 'llama', 'yeti', 'parakeet', 'dolphin']
NUM_CORES = 2
pool = multiprocessing.Pool(NUM_CORES, maxtasksperchild=1)
results = pool.map(nonloop_star, itertools.izip(word_list, itertools.repeat(root_dir)),
chunksize=1)
pool.close()
pool.join()
我不明白你为什么需要在'__name__'块中定义它们,而不是在模块级别,这将起作用。 –
实际上,在块中定义事物对我来说也很好。你为什么认为你需要将所有东西都压缩起来? –
因为Python 2.7的'pool.map'只接受一个函数和一个参数(再次,从我链接的问题)。我很困惑为什么事情正在为你工作 - 也许你可以发布一些有效的代码? – HFBrowning