Почему родительский элемент может отправлять данные только один раз в двунаправленном канале?

#python #python-3.x #multithreading #multiprocessing #python-multiprocessing

#python #python-3.x #многопоточность #многопроцессорная обработка #python-многопроцессорность

Вопрос:

Дочерний процесс может отправлять столько данных, сколько захочет, но родительский процесс может отправить его один раз, затем программа останавливается и ждет чего-то (я не знаю, чего). Канал открыт, я не могу понять, почему это происходит… Я уже просмотрел документацию, но в двунаправленном канале нет примера, только однонаправленный канал.

Код:

 from multiprocessing import Process, Pipe, current_process
from multiprocessing.connection import wait

def foo(w, i):
    print("w -> 1234")
    w.send("1234")

    readers = []

    readers.append(w)

    while readers:
        for r in wait(readers):
            try:
                msg = r.recv()
            except EOFError:
                print("w: error")
                readers.remove(r)
            else:

                if(msg == "1234"):
                    w.send("4321")
                    print("1234 -> w -> 4321")

                if(msg == "4321"):
                    print("4321 -> w")
                    print("w: close")


if __name__ == '__main__':

    readers = []
    r, w = Pipe(duplex=True)
    readers.append(r)
    p = Process(target=foo, args=(w, 1))
    p.start()
    w.close()

    while readers:
        for r in wait(readers):
            try:
                msg = r.recv()
                if(msg == "1234"):
                    r.send("1234")
                    print("1234 -> r -> 1234")

                if(msg == "4321"):
                    r.send("r: 4321")
                    print("4321 -> r -> 4321")

            except EOFError:
                print("r: error")
                readers.remove(r)

  

Текущий вывод:

 w -> 1234
1234 -> r -> 1234
1234 -> w -> 4321
4321 -> r -> 4321
  

Ожидаемый результат:

 w -> 1234
1234 -> r -> 1234
1234 -> w -> 4321
4321 -> r -> 4321
4321 -> w
w: close
  

Комментарии:

1. Для чего предназначен второй аргумент foo ( i ) ? Кажется, он не используется.

2. @alani, ты прав, он действительно нигде не используется, но без него код не запускается

3. Ну, в конце концов, кажется, что проблема просто в том, что вы отправляете "r: 4321" , когда он просто ожидает "4321" , и удаление r: , похоже, исправляет это.

4. «… без этого код не запускается». Вы сказали p = Process(target=foo, args=(w)) или p = Process(target=foo, args=(w,)) (с запятой после w )?

5. 1 к @Booboo, здесь вполне возможно использовать кортеж из 1 элемента, если вы правильно поняли синтаксис. Отдельно от этого ваши имена переменных r и w для двух концов канала бесполезны, учитывая, что они двунаправленные — в документах предлагается parent_conn и child_conn .