从C子进程读取数据时,Python挂起

时间:2016-06-24 06:09:13

标签: python c linux

我有一个python GUI,它会在启动时打开一个C子进程,并在关闭时终止C子进程。

从python发送到C并从C发送到python的信号被正确捕获。 但是,在python端接收数据时会出现一些问题。

这是我的计划:

Python代码:

fpi_c = subprocess.Popen(["./FPI_sig"],stdin=subprocess.PIPE,stdout=subprocess.PIPE)

def handle_inform_from_c(signum, frame):

    print("receved:", signum)

    outstr = fpi_c.stdout.read()

    print outstr

signal.signal(signal.SIGUSR1, handle_inform_from_c)

def gui_sense_and_save_fpi_2():

    fpi_c.stdin.write(str(123)+"\n")

    os.kill(fpi_c.pid,signal.SIGUSR1)

,其中gui_sense_and_save_fpi_2与按钮连接。 按下按钮时,数据和信号 SIGUSR1 将被发送到C子进程。

C代码:

void signal_callback_handler2(int signum)
{

    int gpid;
    scanf("%d",&gpid);

    printf("Caught signal %d\n",signum);
    //fclose(stdout);

    signal(SIGUSR1, signal_callback_handler2);
    kill(getppid(),SIGUSR1);

}

int main()
{

     signal(SIGUSR1, signal_callback_handler2);
     while(1)
     {
        sleep(0.5);
     }
     return EXIT_SUCCESS;
}

如果我添加fclose(stdout),我可以在python端捕获由C打印的消息"Caught signal XXX"

但是,关闭stdout会导致PIPE损坏,我无法再发送数据。

如果没有第fclose(stdout)行,程序会挂在第outstr = fpi_c.stdout.read()行。

我在C中的fflush(stdout)和python中的printf之后尝试了fpi_c.stdin.flush(),但它仍然挂起。

挂起时,如果我强制C进程被任务管理器关闭,我可以在python端捕获消息。

似乎python正在等待C的终止。

但是,除非关闭python GUI,否则我不想关闭C进程。

我如何正确发送和接收数据?

感谢。

2 个答案:

答案 0 :(得分:0)

而不是fclose输出流,使用fflush来刷新它,以便写出缓冲区中的内容,父进程可以读取它:

printf("Caught signal %d\n", signum);
fflush(stdout);

答案 1 :(得分:0)

最后找到解决方案......

如果Python尝试从空缓冲区读取数据, 在这种情况下,它将等待来自C的输入并挂起。

原始代码中应该解决两个问题:

  1. fflush(stdout)之后添加printf

    否则,除非调用fflush(stdout),否则输出将被缓冲而不是实际写入。

  2. Python需要知道应该读取多少个字符或多少行。

    不要使用fpi_c.stdout.read()。这将等待C输入并挂起。相反,使用fpi_c.stdout.read(1)来读取1个字符或 fpi_c.stdout.readline()阅读1行。

  3. 像这样。