我一直在使用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