Как передать большие массивы numpy между подпроцессами python без сохранения на диск?

Есть ли хороший способ передать большой кусок данных между двумя подпроцессами 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 для обработки этих буферов занят только обработкой потока информации. Я хочу координировать этот поток информации с несколькими другими частями оборудования, работающими одновременно в «главной» программе, без блокировки друг друга подпроцессов. Мой нынешний подход состоит в том, чтобы немного упаковать данные в подпроцессе перед сохранением на диск, но было бы неплохо передать все деньги «главному» процессу.

26
задан Andrew 17 February 2011 в 19:47
поделиться