0
我是GTK的新手,我正在爲連接到服務器的程序開發GUI。我用fork
將邏輯(命令行客戶端)與GUI分開。邏輯和GUI使用管道進行通信。使用GIOChannel的空管
有時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()
但它不工作過。
有什麼建議嗎?謝謝!
我總是看到'G_IO_IN'條件,'g_io_channel_read_chars()'返回的狀態總是'G_IO_STATUS_NORMAL' – xonya
嗨,我解決了(不明白爲什麼)。在代碼的一部分中,我使用'sizeof()'而不是'strlen()'。在任何地方使用'strlen()'。我仍然無法複製這個問題... 無論如何,謝謝你的答案! – xonya