Можно ли передать многопроцессорную очередь Python дочернему процессу?

У меня есть большой набор данных в системе сбора данных, которую я написал на python, и для передачи очереди от дочернего процесса к родительскому процессу требуется бесконечно много времени. Я хочу сохранить данные, полученные в конце приобретения, и попробовал это, используя queue функция в Multiprocessing, Вместо того, чтобы делать это таким образом, я бы предпочел, чтобы я мог передать сообщение через queue от родителя к ребенку, чтобы сохранить мои данные, прежде чем я уничтожу дочерний процесс. Это возможно? Пример того, что я думал, может выглядеть так:

def acquireData(self, var1, queue):
    import h5py
    # Put my acquisition code here
    queue.get()
    if queue == True:
        f = h5py.File("FileName","w")
        f.create_dataset('Data',data=data)
        f.close()

if __name__ == '__main__': 
    from multiprocessing import Process, Queue
    queue = Queue()
    inter_thread = Process(target=acquireData, args=(var1,queue))
    queue.put(False)
    inter_thread.start()
    while True:
        if not args.automate:
        # Let c++ threads run for given amount of time
            # Wait for stop from OP GUI
        else:
            queue.put(True)
            break
    print("Acquisition finished, cleaning up...")
    sleep(2)
    inter_thread.terminate()

Это разрешено? Если этот тип взаимодействия между процессами разрешен, тогда у меня есть правильная запись? Для справки, у меня есть порядка 9e7 точек данных в массиве, которые я пытаюсь сохранить, и у меня есть 7 массивов, которые просто не передаются моему родительскому процессу своевременно, помещая эти массивы в queue, Спасибо.

1 ответ

Решение

Во-первых, да, передача очереди дочернему элементу является не только законной, но и основной сценарием использования для очередей. Смотрите первый пример в документации, которая делает именно это.

Однако у вас есть некоторые проблемы с вашим кодом:

queue.get()
if queue == True:

Во-первых, ваш queue никогда не будет булево значение Trueэто будет Queue, Вы почти никогда не хотите проверять if x == True: в Python; ты хочешь проверить if x:, Например, if [1, 2]: пройдет, пока if [1, 2] == True: не буду.

Во-вторых, ваш queue это даже не то, что вы хотите проверить в первую очередь. Это не правда или ложь (или не важно, так ли это); это значение, которое основной процесс ставит в очередь, и вы извлекли из него либо правду, либо ложь. Который вы выбросили, как только вы его получили.

Итак, сделайте это:

flag = queue.get()
if flag:

Или проще:

if queue.get():

Я не уверен, что это именно то, что вы хотите или нет. Тот queue.get() будет блокироваться навсегда, пока основной процесс не поместит что-то туда. Это то, что вы хотели? Если так, отлично; вы закончили с этой частью вашего кода. Если нет, вам нужно подумать о том, что вы хотели вместо этого.

Как и было задумано, родитель всегда будет ждать 2 секунды, даже если ребенок закончил задолго до этого. Лучшим решением является join ребенок с тайм-аутом 2 секунды. Тогда ты можешь terminate это если тайм-аут.

Кроме того, вы уверены, что разработанное вами поведение завершения - то, что вы хотите? Вы выполняете "мягкий запрос на удаление" с очередью, затем ждете 2 секунды, а затем выполняете "средний и жесткий запрос" на terminateи никогда не совершать "тяжелое убийство" с kill, Это может быть вполне разумный дизайн, но если это не ваш дизайн, вы реализовали не то, что нужно.

Другие вопросы по тегам