0

我是 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()但它也不起作用。

有什么建议么?谢谢!

4

1 回答 1

0

当您显示的代码也已知有效时,这很难回答。

您至少应该检查condition回调中的参数,也许是某些原因导致有问题的程序中报告了非读取条件?

于 2013-05-22T10:53:24.813 回答