使用命名管道在C++和Python程序中进行IPC时出现挂起的情况

3

我在Unix系统上使用命名管道练习IPC,并尝试使用Python向FIFO文件中写入字符串,然后通过C++程序进行反转。但是Python程序挂起并且没有返回结果。

Python代码用于写入文件:

import os
path= "/home/myProgram"
os.mkfifo(path)
fifo=open(path,'w')
string=input("Enter String to be reversed:\t ")
fifo.write(string)
fifo.close()

程序挂起并且在此处不请求任何输入。我在程序中断时收到以下错误:
Traceback (most recent call last):
  File "writer.py", line 4, in <module>
    fifo=open(path,'w')
KeyboardInterrupt

从文件中读取的C++代码:

#include <fcntl.h>
#include <iostream>
#include <sys/stat.h>
#include <unistd.h>
#include <string>
#include <string.h>

#define MAX_BUF 1024
using namespace std;

char* strrev(char *str){
    int i = strlen(str)-1,j=0;

    char ch;
    while(i>j)
    {
        ch = str[i];
        str[i]= str[j];
        str[j] = ch;
        i--;
        j++;
    }
    return str;

}


int main()
{
    int fd;
    char *myfifo = "/home/myProgram";
    char buf[MAX_BUF];

    /* open, read, and display the message from the FIFO */
    fd = open(myfifo, O_RDONLY);
    read(fd, buf, MAX_BUF);
    cout<<"Received:"<< buf<<endl;
    cout<<"The reversed string is \n"<<strrev(buf)<<endl;
    close(fd);
    return 0;
}

由于编写程序无法运行,无法测试读取器代码,因此无法在此处提及结果。

请帮忙。


我不使用Python,但输出管道可能会阻塞等待另一端开始读取。 - Galik
如果我先运行读取器文件,它将无法找到新创建的文件myProgram.fifo,并返回错误“文件未找到”。 - Khushbu
是的,请不要先运行读取器。先运行写入器。但是尝试在写入器仍在运行时运行读取器。 - Galik
使用您的代码(修复管道位置后),当我在写入程序和读取程序同时运行时它对我起作用(显然先运行写入程序再运行读取程序)。 - Galik
1
尝试使用 char const* myfifo = "/Users/username/Desktop/myProgram"; 替代。 - Eljay
显示剩余12条评论
1个回答

1

open() 中的 Python 代码块。它正在等待读取器。

通常可以切换到非阻塞并使用 os.open()。但是,对于 FIFO,您将收到错误 ENXIO。这基本上相当于没有读取器存在。

因此,FIFO 的“所有者”应该是读取器。这个规则可能只是一种风格问题。我不知道这个限制的具体原因。

下面是一些演示多个读取器和写入器交错的 Python 代码。

    import os
    r1 = os.open('myfifo', os.OS_RDONLY | os.OS_NONBLOCK)
    r2 = os.open('myfifo', os.OS_RDONLY | os.OS_NONBLOCK)
    w1 = os.open('myfifo', os.OS_WRONLY | os.OS_NONBLOCK)
    w2 = os.open('myfifo', os.OS_WRONLY | os.OS_NONBLOCK)
    os.write(w1, b'hello')
    msg = os.read(r1, 100)
    print(msg.decode())
    os.write(w2, b'hello')
    msg = os.read(r2, 100)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接