【发布时间】:2011-06-29 08:39:43
【问题描述】:
有没有一种在不使用磁盘的情况下在两个 python 子进程之间传递大量数据的好方法?这是我希望完成的卡通示例:
import sys, subprocess, numpy
cmdString = """
import sys, numpy
done = False
while not done:
cmd = raw_input()
if cmd == 'done':
done = True
elif cmd == 'data':
##Fake data. In real life, get data from hardware.
data = numpy.zeros(1000000, dtype=numpy.uint8)
data.dump('data.pkl')
sys.stdout.write('data.pkl' + '\\n')
sys.stdout.flush()"""
proc = subprocess.Popen( #python vs. pythonw on Windows?
[sys.executable, '-c %s'%cmdString],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
for i in range(3):
proc.stdin.write('data\n')
print proc.stdout.readline().rstrip()
a = numpy.load('data.pkl')
print a.shape
proc.stdin.write('done\n')
这将创建一个子进程,该子进程生成一个 numpy 数组并将该数组保存到磁盘。然后父进程从磁盘加载阵列。有效!
问题是,我们的硬件生成数据的速度是磁盘读取/写入速度的 10 倍。有没有办法将数据从一个 python 进程传输到另一个纯粹在内存中的进程,甚至可能不复制数据?我可以做类似通过引用传递的事情吗?
我第一次尝试纯粹在内存中传输数据非常糟糕:
import sys, subprocess, numpy
cmdString = """
import sys, numpy
done = False
while not done:
cmd = raw_input()
if cmd == 'done':
done = True
elif cmd == 'data':
##Fake data. In real life, get data from hardware.
data = numpy.zeros(1000000, dtype=numpy.uint8)
##Note that this is NFG if there's a '10' in the array:
sys.stdout.write(data.tostring() + '\\n')
sys.stdout.flush()"""
proc = subprocess.Popen( #python vs. pythonw on Windows?
[sys.executable, '-c %s'%cmdString],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
for i in range(3):
proc.stdin.write('data\n')
a = numpy.fromstring(proc.stdout.readline().rstrip(), dtype=numpy.uint8)
print a.shape
proc.stdin.write('done\n')
这非常慢(比保存到磁盘慢得多)并且非常非常脆弱。一定有更好的方法!
只要数据获取进程不阻塞父应用程序,我就不会与“子进程”模块结婚。我短暂地尝试了“多处理”,但到目前为止没有成功。
背景:我们有一个硬件可以在一系列 ctypes 缓冲区中生成高达 ~2 GB/s 的数据。处理这些缓冲区的 python 代码只是处理大量的信息。我想将这种信息流与在“主”程序中同时运行的其他几个硬件协调起来,而子进程不会相互阻塞。我目前的方法是在保存到磁盘之前在子进程中将数据煮沸一点,但最好将完整的数据传递给“主”进程。
【问题讨论】:
-
听起来线程很适合你。
-
@Gabi Purcaru 因为我对线程一无所知。随时用答案教育我!
-
避免腌制 numpy 数组。请改用
numpy.save(file, arr)。腌制一个数组会使用大量的中间内存(尤其是默认情况下),而且速度相当慢。numpy.save效率更高。 -
安德鲁,你事先知道数据的总大小吗?还是最大尺寸?
-
@Joe Kington:好电话。对于约 200 MB 的数组,numpy.save() 比 numpy.dump() 节省了一点时间,(7.3 秒 -> 6.5 秒),但它减少了一半的内存使用。
标签: python numpy subprocess pass-by-reference ctypes