我是 GTK 的新手,我正在为连接到服务器的程序开发 GUI。我使用 afork
将逻辑(命令行客户端)与 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()
但它也不起作用。
有什么建议么?谢谢!