在C和Python之间读取和写入Fifo文件

Reading and Writing Fifo Files between C and Python

通常,我正在创建两个由我的.c和.py程序读取和写入的fifo队列。为了使.c程序能够与python交互,我包含了<python2.7/Python.h>库。

首先,我的.c程序创建一个名为CFifo的文件,并使用fprintf向其中写入文本。没问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <python2.7/Python.h>


int main() {
    FILE *CFifo, *pythonFifo, *pythonFile;
    char buffer[1024];

    // declare python
    Py_SetProgramName("writer.py");

    // init python
    Py_Initialize();

    // open python
    pythonFile = fopen("writer.py","r");

    // C writes to file, python reads from this file
    CFifo = fopen("./CFifo","w");  

    // Print strings to file using fprintf
    fprintf(CFifo,"This is a test");

    // close file python reads
    fclose(CFifo);

我的C程序的第二部分应该读取我的python程序写入的信息(在第二个fifo队列中),但是当打开./pythonFifo时,它只是挂在终端中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    // make second fifo queue
    // python writes to this file, C reads from it
    mkfifo("./pythonFifo", 0777);

    // run python program
    PyRun_SimpleFile(pythonFile,"writer.py");
    pythonFifo = fopen("./pythonFifo","r");

    while(fgets (buffer, sizeof(buffer), pythonFifo)) {
        printf("%s", buffer);
    }

    // close python
    Py_Finalize();
    fclose(pythonFifo);
    remove("./pythonFifo");

    return 0;
}

这是负责写入fifo队列的python部分。

1
2
3
4
5
6
# open fifo file that python writes to
filename_write ="./pythonFifo"
pipe = os.open(filename_write, os.O_WRONLY)
for output in finalStringList:
   os.write(pipe, output)
os.close(pipe)

第二个文件的目的是写入从第一个文件读取的修改信息。


您不能从这里到达那里。从mkfifo手册页...

Once you have created a FIFO special file in this way, any process
can open it for reading or writing, in the same way as an ordinary
file. However, it has to be open at both ends simultaneously before
you can proceed to do any input or output operations on it. Opening a
FIFO for reading normally blocks until some other process opens the
same FIFO for writing, and vice versa.

双方都需要先打开文件,然后才能继续。但是,由于PyRun_SimpleFile同步运行python脚本,因此从未打开用于打开文件的后C代码。如果您尝试先在C代码中打开它,则它将在运行python代码之前挂起。您有一个经典的死锁。

我在您的样本中添加了几张照片,并且能够像在单独的控制台中执行cat pythonFifoecho foo > pythonFifo一样看到程序的进展。它当然返回了垃圾,但是证明了问题所在。

实际上,您可以从这里到达那里(同样,手册页)

See fifo(7) for nonblocking handling of FIFO special files.

但是,如果您的python代码写的内容超出了管道的容纳范围,则您将更容易陷入僵局。您最好将python程序写入某个变量,然后让C代码从那里读取它。