我是GTK的新手,我正在为连接到服务器的程序开发GUI。我使用fork
将逻辑(命令行客户端)与GUI分开。逻辑和GUI使用管道进行通信。
有时GUI会从管道中读取几条空信息,我不明白为什么。
我尝试制作SSCCE,但我无法在简化示例中复制该问题。无论如何,这大致是该计划的运作方式:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gtk/gtk.h>
int gui_pipe[2], logic_pipe[2];
gboolean deliver_signal(GIOChannel *source, GIOCondition cond, gpointer d) {
gchar readbuffer[100];
char ack[] = "ack";
read(gui_pipe[0], readbuffer, 100);
g_print("I received: %s\n",readbuffer);
write(logic_pipe[1], ack, strlen(ack));
return(TRUE);
}
main(int argc, char *argv[]) {
GtkBuilder *builder;
GtkWidget *window;
GIOChannel *g_signal_in;
if(pipe(gui_pipe)==-1) {
perror("pipe call");
exit(1);
}
if(pipe(logic_pipe)==-1) {
perror("pipe call");
exit(1);
}
switch(fork()) {
case -1:
perror("fork call");
exit(2);
case 0: /* Child (GUI) */
close(gui_pipe[1]);
close(logic_pipe[0]);
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file(builder, "mygui.glade", NULL);
window = GTK_WIDGET(gtk_builder_get_object(builder, "window1"));
g_signal_in = g_io_channel_unix_new(gui_pipe[0]);
g_io_add_watch(g_signal_in, G_IO_IN, deliver_signal, NULL);
gtk_widget_show(window);
gtk_main();
default: /* Parent (Logic) */
close(gui_pipe[0]);
close(logic_pipe[1]);
char msg[] = "Hello!";
char readbuffer[100];
int i;
for(i=0;i<5;i++) {
printf("LOGIC: I'm sending %s\n",msg);
write(gui_pipe[1], msg, strlen(msg));
read(logic_pipe[0], readbuffer, 100);
printf("LOGIC: I received: %s\n", readbuffer);
}
exit(0);
}
}
此版本不读取空管道,但原始程序会执行此操作(总是7次!)。 我发现的唯一解决方案是:
do {
read(gui_pipe[0], readbuffer, 100);
} while(strcmp("",readbuffer)==0);
我还尝试使用g_io_channel_read_chars()
代替read()
,但它也不起作用。
有什么建议吗?谢谢!
答案 0 :(得分:0)
当您显示的代码也已知可行时,很难回答。
你至少应该检查一下你的回调中的condition
参数,也许是因为有问题的程序会导致non-read conditions报告?