Есть ли хороший способ передать большой кусок данных между двумя подпроцессами 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')
Это очень медленно (намного медленнее, чем сохранение на диск) и очень, очень хрупко. Должен быть способ получше!
Я не замужем за модулем 'subprocess', пока процесс сбора данных не блокирует родительское приложение. Я кратко попробовал «многопроцессорность», но пока безуспешно.
Предыстория: у нас есть аппаратное обеспечение, которое генерирует до ~ 2 ГБ / с данных в серии буферов ctypes. Код Python для обработки этих буферов занят только обработкой потока информации. Я хочу координировать этот поток информации с несколькими другими частями оборудования, работающими одновременно в «главной» программе, без блокировки друг друга подпроцессов. Мой нынешний подход состоит в том, чтобы немного упаковать данные в подпроцессе перед сохранением на диск, но было бы неплохо передать все деньги «главному» процессу.