0

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()たが、うまくいきません。

助言がありますか?ありがとう!

4

1 に答える 1