我在尝试让 C++ 进程通过 FIFO 与 Python 进程通信时遇到问题。
这些进程通过 2 个 FIFO 使用 2 路通信:
这个想法是两个进程在每个周期都进行写入和读取。 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 上一个循环等等),结果如下:
如果我运行 2 个或更多 C++ 周期,然后在 Python 进程上运行一个周期,则不会丢失任何数据,并且工作得很好
如果我在 C++ 进程运行时运行 Python 进程两次,那么 Python 进程就会崩溃。但是,如果 C++ 进程关闭,则不会发生崩溃,并且 fifo 工作正常
出于好奇,如果将 getchar() 移至循环开头、指令之前会发生什么?