我有一个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进程。
我如何正确发送和接收数据?
感谢。
答案 0 :(得分:0)
而不是fclose
输出流,使用fflush
来刷新它,以便写出缓冲区中的内容,父进程可以读取它:
printf("Caught signal %d\n", signum);
fflush(stdout);
答案 1 :(得分:0)
最后找到解决方案......
如果Python尝试从空缓冲区读取数据, 在这种情况下,它将等待来自C的输入并挂起。
原始代码中应该解决两个问题:
在fflush(stdout)
之后添加printf
。
否则,除非调用fflush(stdout)
,否则输出将被缓冲而不是实际写入。
Python需要知道应该读取多少个字符或多少行。
不要使用fpi_c.stdout.read()
。这将等待C输入并挂起。相反,使用fpi_c.stdout.read(1)
来读取1个字符或
fpi_c.stdout.readline()
阅读1行。
像这样。