使用管道

时间:2018-03-07 03:39:15

标签: python c pipe

我试图将数据从C程序发送到python程序(两者同时运行)。我试图在C中使用popen函数。我理解它的方式,无论我写入C语言中的文件描述符,都可以从python程序中的stdin读取。但是,python程序似乎挂起它从stdin读取的位置。有什么建议吗?

这是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);
}

这是python程序,它应该读取&#34; inc&#34;的值。输出

display.py

import sys

value = 0

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

该程序似乎挂在 value = sys.stdin.read()。我也尝试过readline()和readlines()以及相同的结果。

2 个答案:

答案 0 :(得分:4)

如果您从C程序输出,则

readline()会有效。

由于您从不打印换行符,readline将永远等待。

没有参数的

read()将等待C程序退出(或以其他方式关闭stdout)。再一次,你的程序永远不会发生这种情况

答案 1 :(得分:1)

您宁愿使用fprintf(3)而不是将sprintf(不安全,更喜欢snprintf(3))与fputs混合。

你真的想输出整行(因为textual protocols非常方便调试)。并在Python端使用readline

最后,由popen(3)获得的FILE*甚至不能保证是行缓冲的(但可能有更大的缓冲区,可能是4K字节或更多)。您可以使用setvbuf(3)设置其缓冲区,但您确实应该使用fflush(3) 明确刷新FILE*缓冲区。如果不这样做,输出可能会长时间保留在缓冲区中(stdio函数(fprintffputs之后没有任何实际的write(2)完成)所以{ {3}}保持空白。

(所以即使在C方面也有问题)

  

该程序似乎挂在value = sys.stdin.read()。

我猜你的C代码实际上并没有写一个字节(你可以使用pipe(7)进行检查),因为你的fputs留在缓冲区中。您可能需要等待很长时间(可能需要1000秒,以填充几千字节的缓冲区)才能让它实际在管道上写入内容,因为您忘记了fflush

popen - ed文件绝对应为pclose d。

所以你应该用(

)替换你的(不正确的)while循环
while(1) {
    fprintf(fp, "%d\n", inc);
    inc++;
    fflush(fp);
    sleep(1);
}

你的循环应该以某种方式退出。也许你可能会遇到一些strace(1) - 可能SIGTERM - (但一定要阅读signal(7))。请务必pclose(以避免僵尸进程)。

(我假设您使用的是Linux或其他POSIX系统)