C++/Python 使用 FIFO 处理 IPC:无法从 Python 连续读取两次

问题描述 投票:0回答:1

我在尝试让 C++ 进程通过 FIFO 与 Python 进程通信时遇到问题。

这些进程通过 2 个 FIFO 使用 2 路通信:

  • C++ 在 pythonread_fifo 上写入,反之亦然,Python 从中读取
  • Python 进程在 cppread_fifo 上写入,反之亦然,C++ 从那里读取

这个想法是两个进程在每个周期都进行写入和读取。 Python 写为“woof”,C++ 写为“quack”。

如果 2 个进程中的一个比另一个更快(比如 C++ 执行 3 个周期,而 python 仍然停留在第一个周期),那么我希望另一个进程不会遭受数据丢失(在我的示例中,python 将收到嘎嘎嘎嘎)。

我的代码似乎可以工作,直到我尝试让 Python 进程连续循环两次,而 C++ 被冻结,这触发了错误:

BlockingIOError: [Errno 11] 第 24 行资源暂时不可用:os.read(fd[0], 20)

这是代码;请注意,只有 Python 进程调用 mkfifo,因为这是项目中所需的行为:

管道.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();
    }
}

管道.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 上一个循环等等),结果如下:

Normal Flow: C++->Python->C++->Python

如果我运行 2 个或更多 C++ 周期,然后在 Python 进程上运行一个周期,则不会丢失任何数据,并且工作得很好

C++->C++->C++>Python

如果我在 C++ 进程运行时运行 Python 进程两次,那么 Python 进程就会崩溃。但是,如果 C++ 进程关闭,则不会发生崩溃,并且 fifo 工作正常

enter image description here

python c++ pipe ipc mkfifo
1个回答
0
投票

出于好奇,如果将 getchar() 移至循环开头、指令之前会发生什么?

© www.soinside.com 2019 - 2024. All rights reserved.