C ++ / Python Обрабатывает IP C с FIFO: невозможно прочитать дважды подряд из Python - PullRequest
1 голос
/ 18 июня 2020

У меня проблемы с попыткой заставить процесс C ++ взаимодействовать с Python одним через FIFO.

Эти процессы используют двустороннюю связь через 2 FIFO:

  • C ++ пишет на pythonread_fifo и наоборот, Python читает из него
  • процесс Python записывает на cppread_fifo и наоборот, C ++ читает оттуда

Идея заключается в том, что оба процессы пишут и читают в каждом цикле. Один Python пишет «woof», а C ++ пишет «quack».

Если один из двух процессов быстрее другого (например, C ++ выполняет 3 цикла, а python все еще застревает на первый), то я ожидаю, что другой не пострадает от потери данных (в моем примере python получит quackquackquack).

Мой код, казалось, работал, пока я не попытался разрешить процессу Python цикл дважды подряд, пока C ++ был заморожен, что вызвало ошибку:

BlockingIOError: [Errno 11] Ресурс временно недоступен в строке 24: os.read (fd [0], 20)

Вот код; обратите внимание, что только процесс Python вызывает mkfifo, потому что это желаемое поведение в проекте:

pipe. cpp

#define MAX_BUF 1024

const char * write_path = "python_cpp_comms/pythonread_fifo";
const char * read_path =  "python_cpp_comms/cppread_fifo";

int main(int argc, char**argv)
{
    int fd[2];
    char buf[MAX_BUF];

    printf("Opened\n");
    fd[1] = open(write_path, O_RDWR);
    fd[0] = open(read_path, O_RDONLY | O_NONBLOCK);
    int cycle = 1;
    for(;;) {
        printf("Cycle: %d\n",cycle++);
        int out = write(fd[1], "quack", 5);
        printf("Written %d bytes errno=%d:\n", out, errno);
        int in = read(fd[0], buf, MAX_BUF);
        printf("Received %d bytes errno=%d: %*.*s\n", in, errno, in,in, buf);
        std::cout << "Doing something \n";
        getchar();
    }
}

pipe .py

read_path =  "python_cpp_comms/pythonread_fifo"
write_path = "python_cpp_comms/cppread_fifo"

if __name__ == "__main__":
    try:
        os.mkfifo(read_path)
    except:
        pass
    try:
        os.mkfifo(write_path)
    except:
        pass

    print("Opening FIFO...")

    fd = []
    fd.append(os.open(read_path, os.O_RDONLY | os.O_NONBLOCK))
    fd.append(os.open(write_path, os.O_RDWR))
    cycle = 1

    while True:
        print("Cycle: {}".format(cycle))
        data = os.read(fd[0], 20)
        if len(data) == 0:
            print("Writer closed")
        print('Received: "{0}"'.format(data))
        print("writing 'woof'")
        os.write(fd[1], b'woof')
        cycle += 1
        print("Doing something\n")
        input()

Как видите, здесь я использую getchar / input для управления потоком.

Итак, в простой ситуации, когда я делаю 2 процессы продвигаются вперед один за другим (один цикл на C ++ и один на Python и так далее), результат будет следующим:

imagePython->C++->Python">

Если я запустите 2 или более циклов C ++, а затем запустите цикл для процесса Python, данные не теряются, и он работает нормально

imageC++->C++>Python">

Если я вместо этого дважды запустите процесс Python, КОГДА ПРОЦЕСС C ++ ЗАПУСКАЕТСЯ, тогда процесс Python выйдет из строя. Однако, если процесс C ++ ЗАКРЫТ, cra sh не происходит, а FIFO работает нормально

enter image description here

...