我可能会问一个非常基本的问题,但我真的无法想象如何在python中创建一个简单的并行应用程序。 我在一个16核的机器上运行我的脚本,我想有效地使用它们。我有16个巨大的文件要读取,我希望每个cpu读取一个文件,然后合并结果。 在这里,我举一个简单的例子说明我想做什么:
parameter1_glob=[]
parameter2_glob[]
do cpu in arange(0,16):
parameter1,parameter2=loadtxt('file'+str(cpu)+'.dat',unpack=True)
parameter1_glob.append(parameter1)
parameter2_glob.append(parameter2)
我认为multiprocessing
模块可能会有所帮助,但我无法理解如何将其应用于我想要做的事情。
答案 0 :(得分:2)
我同意Colin Dunklau在评论中所说的,这个过程会在读取和写入这些文件时遇到瓶颈,CPU需求很小。即使你有17个专用驱动器,你也不会想到一个核心。另外,虽然我意识到这与你的实际问题相关,你可能会遇到这些“巨大”文件的内存限制 - 将16个文件作为数组加载到内存中,然后将它们组合到另一个文件中几乎肯定会占用更多内存。你有。
您可以找到更好的结果来查看shell脚本这个问题。特别是,GNU sort
使用内存高效的合并排序来快速排序一个或多个文件 - 比使用Python或大多数其他语言编写的最精心编写的应用程序快得多。
我建议避免任何类型的多线程工作,它会极大地增加复杂性,并且收益最小。确保一次将少量文件保留在内存中,否则会很快耗尽。无论如何,您绝对希望在两个单独的磁盘上运行读写操作。与同时读取和写入同一磁盘相关的减速非常痛苦。
答案 1 :(得分:1)
您想逐行合并吗?对于I / O绑定应用程序,有时协程程序比传统的多任务处理更有趣。您可以为所有类型的路由,合并和广播链接生成器和协同程序。用这个nice presentation by David Beazley吹响你的想法。
您可以使用协程作为接收器(未经测试,请参阅dabeaz示例):
# A sink that just prints the lines
@coroutine
def printer():
while True:
line = (yield)
print line,
sources = [
open('file1'),
open('file2'),
open('file3'),
open('file4'),
open('file5'),
open('file6'),
open('file7'),
]
output = printer()
while sources:
for source in sources:
line = source.next()
if not line: # EOF
sources.remove(source)
source.close()
continue
output.send(line)
答案 2 :(得分:0)
假设每个文件的结果都很小,您可以使用我的包jug执行此操作:
from jug import TaskGenerator
loadtxt = TaskGenerator(loadtxt)
parameter1_glob=[]
parameter2_glob[]
@TaskGenerator
def write_parameter(oname, ps):
with open(oname, 'w') as output:
for p in ps:
print >>output, p
parameter1_glob = []
parameter2_glob = []
for cpu in arange(0,16):
ps = loadtxt('file'+str(cpu)+'.dat',unpack=True)
parameter1_glob.append(ps[0])
parameter2_glob.append(ps[1])
write_parameter('output1.txt', parameter1_glob)
write_parameter('output2.txt', parameter2_glob)
现在,您可以执行多个jug execute
个工作。