【问题标题】:C to Python piping - How to detect reader accessC 到 Python 管道 - 如何检测读取器访问
【发布时间】:2021-05-07 22:18:03
【问题描述】:

我正在使用 C 程序写入命名管道,并使用 Python 程序读取它。

如果我停止 Python 程序(阅读器),那么编写器会自行停止,尽管这是在 while(1) 循环中。为什么会这样?是无声的崩溃吗?

第二个问题,如果我想检测阅读器何时断开连接,我应该怎么做。我的理想方案是检测断开连接然后继续空闲(即停止发送任何内容)并在阅读器返回后恢复。

下面的玩具代码。

作家(C):

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
  
int main()
{
    int fd;
  
    // FIFO file path
    char * myfifo = "/tmp/myfifo";
  
    // Creating the named file(FIFO)
    // mkfifo(<pathname>, <permission>)
    mkfifo(myfifo, 0666);
  
    char arr1[80];
    while (1)
    {
        // Open FIFO for write only
        fd = open(myfifo, O_WRONLY);
  
        // Take an input from user.
        fgets(arr1, 80, stdin);
  
        // Write the input on FIFO
        // and close it
        write(fd, arr1, strlen(arr1)+1);
        close(fd);
    }
    return 0;
}

阅读器(Python)

f = open("/tmp/myfifo")
while 1:
    print(f.readline(), end = "")

f.close()

【问题讨论】:

    标签: python c named-pipes


    【解决方案1】:

    当您停止读取程序时,写入器将在尝试写入管道时收到SIGPIPE 信号。该信号的默认处置是终止进程。

    如果要检测这种情况,请使用signal()sigaction() 将处置更改为SIG_IGN。然后写入管道会报EPIPE错误。

    此外,您不应在每次通过循环时关闭并重新打开管道。开始时打开一次,结束时关闭。关闭管道会导致读取器获得 EOF,之后将无法读取任何内容。

    #include <stdio.h>
    #include <string.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <signal.h>
      
    int main()
    {
        int fd;
      
        // FIFO file path
        char * myfifo = "/tmp/myfifo";
        
        // Creating the named file(FIFO)
        // mkfifo(<pathname>, <permission>)
        mkfifo(myfifo, 0666);
        // Open FIFO for write only
        fd = open(myfifo, O_WRONLY);
      
        signal(SIGPIPE, SIG_IGN);
    
        char arr1[80];
        while (1)
        {
      
            // Take an input from user.
            fgets(arr1, 80, stdin);
      
            // Write the input on FIFO
            // and close it
            int res = write(fd, arr1, strlen(arr1)+1);
            if (res < 0) {
                perror("write");
                break;
            }
        }
        close(fd);
        return 0;
    }
    

    当您停止写入程序时,读取器在尝试从管道读取时会得到 EOF。当f.readline() 到达 EOF 时,它返回一个空字符串。您的 Python 脚本不会对此进行检查,因此它会无限循环。

    将阅读器更改为:

    with open("/tmp/myfifo") as f:
        while True:
            line = f.readline()
            if not line:
                break
            print(line, end = "")
    

    然后当管道关闭时循环将终止。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-24
      • 2018-10-04
      • 1970-01-01
      • 1970-01-01
      • 2012-01-01
      相关资源
      最近更新 更多