我试图使用Python的多处理地图功能。我把地图调用放在一个子函数中,因为我需要循环一个更大的数据集来分割它并在较小的块上调用map。
我的问题是time.sleep(5)行被多次调用并且'测试!'正在打印5次(在开始时看起来等于一次,然后循环次数为2 * 2 *进程数),即使它处于比多处理调用更高的级别。但是,同时,CSV输出是我所期望的,因此runParallel()按预期运行并被称为预期的次数。
from multiprocessing import Pool
import numpy as np
import os,csv,copy,time
from AuxFuncs import *
def master():
time.sleep(5)
print('Test!')
for mult in [1,10]:
runParallel(mult)
def runParallel(mult):
randIntInputs = list()
for i in range(5): randIntInputs.append((np.random.randint(10)*mult,mult))
if __name__=='__main__':
p = Pool(processes=2)
results = p.map(testFunc,randIntInputs)
p.close()
p.join()
valsToSave = [list(result[0]) for result in results]
write2dListToCSV(valsToSave,'output' + str(mult) + '.csv')
def testFunc(inputs):
return np.random.randint(1,10,5) * inputs[0],inputs[1]
master()
输出是:
Test!
Test!
Test!
Test!
Test!
我认为问题可能是我将Pool调用放在一个函数中,但即使我将它移出函数,我也有同样的问题("测试!"打印3次通过以下代码。)
from multiprocessing import Pool
import numpy as np
import os,csv,copy,time
from AuxFuncs import *
def testFunc(inputs):
return np.random.randint(1,10,5) * inputs[0],inputs[1]
print('Test!')
mult,randIntInputs = 5,list()
for i in range(5): randIntInputs.append((np.random.randint(10)*mult,mult))
if __name__=='__main__':
p = Pool(processes=2)
results = p.map(testFunc,randIntInputs)
p.close()
p.join()
valsToSave = [list(result[0]) for result in results]
write2dListToCSV(valsToSave,'output' + str(mult) + '.csv')
编辑: 谢谢您的帮助。看起来像这样:
来自多处理导入池 导入numpy为np import os,csv,copy,time 来自AuxFuncs import *
def master():
if __name__=='__main__':
time.sleep(5)
print('Test!')
for mult in [1,10]:
runParallel(mult)
def runParallel(mult):
randIntInputs = list()
for i in range(5): randIntInputs.append((np.random.randint(10)*mult,mult))
# if __name__=='__main__':
p = Pool(processes=2)
results = p.map(testFunc,randIntInputs)
p.close()
p.join()
valsToSave = [list(result[0]) for result in results]
write2dListToCSV(valsToSave,'output' + str(mult) + '.csv')
def testFunc(inputs):
return np.random.randint(1,10,5) * inputs[0],inputs[1]
master()
答案 0 :(得分:0)
这里可能发生的是每个进程都在尝试导入您调用的函数。当发生这种情况时,它会运行在定义之外调用的任何函数,或者不会被if
屏蔽,包括您对master
的调用。将if __name__ ...
放在定义中不允许您使用它来屏蔽其他操作。我认为你的目标看起来更像是这样:
def master():
time.sleep(5)
print('Test!')
for mult in range(1, 11):
runParallel(mult)
def runParallel(mult):
randIntInputs = list()
for i in range(5): randIntInputs.append((np.random.randint(10)*mult,mult))
with Pool(processes=2) as p:
results = p.map(testFunc,randIntInputs)
valsToSave = [list(result[0]) for result in results]
write2dListToCSV(valsToSave,'output' + str(mult) + '.csv')
def testFunc(inputs):
return np.random.randint(1,10,5) * inputs[0],inputs[1]
if __name__ == '__main__':
master()
这与您上一次更新之间的区别在于,在您的更新主数据库仍然为每个进程调用时,它只是没有做任何事情,因为if
语句没有评估True
;但在此代码中,它只调用master
一次,并在if
语句之后每次都被阻止。差异并不大,但这个版本更加实用。
顺便说一句,我冒昧地使用with
语句将您的池放在上下文管理器中。一旦上下文退出,这将自动关闭Pool
。我还删除了.join()
因为Pool().map()
函数已经暂停主线程直到它返回。最后,我将您在master中创建的临时列表更改为对range
的调用。 range
用于在输入的两个之间创建一系列数字,包括左侧但不包括右侧。使用单个参数,它使用0作为起始点并上升到指定的数字; range(10) => 0 1 2 3 4 5 6 7 8 9
。