简体   繁体   English

使用管道将数据从C进程发送到Python进程

[英]Sending data from C process to Python process using pipes

I'm trying to send data from a C program to a python program (both are running simultaneously). 我正在尝试将数据从C程序发送到python程序(两者同时运行)。 I'm attempting to use the popen function in C. The way I understand it, whatever I write to the file descriptor in C can be read from stdin in the python program. 我试图在C中使用popen函数。据我了解,无论我在C中写入文件描述符的什么内容,都可以从python程序的stdin中读取。 However, the python program appears to hang at the point where it reads from stdin. 但是,python程序似乎挂在从stdin读取的位置。 Any suggestions? 有什么建议么?

Here's the C program: 这是C程序:

test.c 测试

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void) {

    FILE * fp = popen("sudo python display.py", "w");
    if (fp == NULL) {
        printf("popen error\n");
        exit(1);
    }

    int inc = 0;
    char buf[10];

    while(1) {
        sprintf(buf, "%d", inc);
        fputs(buf, fp);
        inc++;
        sleep(1);
    }


    return (0);
}

Here is the python program, which should read the value of "inc" and output it 这是python程序,应读取“ inc”的值并将其输出

display.py display.py

import sys

value = 0

while(True):
    value = sys.stdin.read()
    print value

The program seems to hang at value = sys.stdin.read() . 该程序似乎挂在value = sys.stdin.read()上 I have tried readline() and readlines() as well with the same result. 我也尝试过readline()和readlines(),结果相同。

readline() would work if you were outputting lines from your C program. 如果从C程序输出 ,则readline()将起作用。

Since you never print a newline, readline will wait forever. 由于您从不打印换行符,因此readline将永远等待。

read() with no parameters will wait until the C program exits (or otherwise closes stdout). 没有参数的read()将等到C程序退出(否则关闭stdout)。 Again this is never going to happen with your program 同样,程序永远不会发生这种情况

You rather should use fprintf(3) instead of mixing sprintf (which is unsafe, prefer snprintf(3) ) with fputs . 您应该使用fprintf(3)而不是将sprintf (这是不安全的,更喜欢snprintf(3) )与fputs

You really want to output whole lines (because textual protocols are so convenient to debug). 您确实想输出整行(因为文本协议调试起来非常方便)。 And use readline on the Python side. 并在Python端使用readline

At last, a FILE* obtained by popen(3) is not even guaranteed to be line-buffered (but could have a much larger buffer, perhaps 4Kbytes or more). 最后,甚至不能保证由popen(3)获得的FILE*是行缓冲的(但是可能具有更大的缓冲区,也许4KB或更多)。 You might set its buffer using setvbuf(3) but you really should flush explicitly the FILE* buffer with fflush(3) . 您可以使用setvbuf(3)设置其缓冲区,但实际上应该使用fflush(3)显式刷新FILE*缓冲区 If you don't, the output could stay in the buffer for a long time (without any actual write(2) done by stdio functions like fprintf or fputs ) so the pipe(7) stays empty. 如果不这样做,则输出可能会在缓冲区中保留很长时间(没有由诸如fprintffputs类的stdio函数完成的实际write(2) ),因此pipe(7)保持为空。

(so you have problems even on the C side) (因此即使在C端,您也有问题)

The program seems to hang at value = sys.stdin.read(). 该程序似乎挂在值= sys.stdin.read()。

I guess that not a single byte was actually written by your C code (you could check by using strace(1) ) because your fputs stayed in the buffer. 我想您的C代码实际上并没有写一个字节(您可以使用strace(1)进行检查),因为fputs停留在缓冲区中。 You might need to wait a long time (perhaps 1000 seconds, to fill a buffer of a few kilobytes) to have it actually write something on the pipe, because you forgot the fflush . 您可能需要等待很长时间(可能是1000秒,以填充几千字节的缓冲区),以使其实际上在管道上写东西,因为您忘记了fflush

A popen -ed file should absolutely be pclose d. 一个popen -ed文件要绝对pclose d。

So you should replace your (incorrect) while loop with: 因此,您应该将(不正确的) while循环替换为:

while(1) {
    fprintf(fp, "%d\n", inc);
    inc++;
    fflush(fp);
    sleep(1);
}

And your loop should be exited somehow. 而且您的循环应该以某种方式退出。 Perhaps you might catch some signal(7) -probably SIGTERM - (but be sure to read signal-safety(7) ). 也许你会听到一些信号(7) -可能SIGTERM - (但一定要读信号安全(7) )。 Be sure to pclose (to avoid zombie processes). 确保pclose (以避免僵尸进程)。

(I am assuming you are on Linux or some other POSIX system) (我假设您使用的是Linux或其他POSIX系统)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM