Python多处理w/Map:运行整个脚本,而不仅仅是子函数
我正在尝试使用Python的多处理映射函数。我将map调用放在一个子函数中,因为我需要循环通过一个较大的数据集来划分它,并在较小的块上调用map 我的问题是,time.sleep(5)行被多次调用并被称为“Test!”打印5次(开始时似乎等于一次,然后循环数*进程数等于2*2),即使它的级别高于多处理调用。但同时,CSV输出是我所期望的,因此runParallel()按预期运行并被调用了预期的次数Python多处理w/Map:运行整个脚本,而不仅仅是子函数,python,dictionary,multiprocessing,pool,Python,Dictionary,Multiprocessing,Pool,我正在尝试使用Python的多处理映射函数。我将map调用放在一个子函数中,因为我需要循环通过一个较大的数据集来划分它,并在较小的块上调用map 我的问题是,time.sleep(5)行被多次调用并被称为“Test!”打印5次(开始时似乎等于一次,然后循环数*进程数等于2*2),即使它的级别高于多处理调用。但同时,CSV输出是我所期望的,因此runParallel()按预期运行并被调用了预期的次数 from multiprocessing import Pool import numpy as
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!
我想问题可能是我把池调用放在了一个函数中,但即使我把它移出了一个函数,我也有同样的问题(“Test!”被下面的代码打印了3次。)
编辑:
谢谢你的帮助。看起来这样行得通:
来自多处理导入池
将numpy作为np导入
导入操作系统、csv、拷贝、时间
从AuxFuncs导入*
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()
这里可能发生的情况是,每个进程都试图导入调用的函数。发生这种情况时,它会运行任何在定义之外调用的函数,或者不受
if
屏蔽的函数,包括对主控
的调用。将if\uuuuuu name\uuuuuu…
放在定义中不允许您使用它来屏蔽其他操作。我认为你想要的更像这样:
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
语句将您的池放在上下文管理器中。一旦上下文退出,这将自动关闭池。我还删除了.join()
,因为Pool().map()
函数已经暂停主线程,直到它返回。最后,我将您在master中创建的临时列表更改为对范围的调用<代码>范围
用于在输入的两个数字之间创建数字序列,包括左侧但不包括右侧。对于单个参数,它使用0作为起点,并上升到指定的数字<代码>范围(10)=>01 2 3 4 5 6 7 8 9
我对您选择的代码结构感到非常困惑。为什么testFunc
嵌套在runParallel
中?然后您还可以在runParallel
内部继续打开和关闭池
,因为该函数是在master()
中的for
循环中调用的。我认为最好重构这个,然后看看这个行为是否仍然存在。好的,编辑更有意义。如果您将print('Test!')
放在下,如果uuuu name\uuuuuu=='\uuuuu main\uuuuu'
则您会发现它只打印一次。这样行吗?你在Windows上吗?对不起。。。格式不好。testFunc未嵌套在runParallel中。是的,我在Windows上,是的,正在进行测试!在“if name…”内部解决了第二个代码块中的问题。我将池调用本质上放在for循环中,因为如果我将所有数据都放在一个函数调用中,我正在处理的数据集将花费太长时间。所以我把它分成几个块,对每个块进行计算(w/多重处理),然后保存每个块。好的,你的评论让我意识到我可以将if name=='main'调用移到我的master()函数中,这一切似乎都起作用了。像这样:我真的认为您应该像第二个示例中那样保留代码,并使用if uuu name\uuuu=='\uuu main\uuu'
屏蔽您不希望在每个子进程中运行的代码,而不是将其放在函数中谢谢!!看起来你和roganjosh在if主语句应该在哪里达成了一致,所以我把它作为主调用的包装。还很高兴知道.join()是多余的,就像while框架一样。我在我的主剧本上试过了,一切都如期进行。再次感谢你!没问题。顺便说一句,如果你打算留下来的话,请拿着这个。一般准则要求我们不要在评论中表示感谢,而是通过向上投票和选择答案来表示感谢。如果你喜欢我的答案,请勾选我答案旁边的绿色复选标记。
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()