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()
たが、うまくいきません。
助言がありますか?ありがとう!