2013-05-22 17 views
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()但它不工作過。

有什麼建議嗎?謝謝!

回答

0

當您顯示的代碼也已知可以正常工作時,很難回答。

您至少應該在回調中檢查condition參數,或許是在有問題的程序中報告non-read conditions

+0

我總是看到'G_IO_IN'條件,'g_io_channel_read_chars()'返回的狀態總是'G_IO_STATUS_NORMAL' – xonya

+0

嗨,我解決了(不明白爲什麼)。在代碼的一部分中,我使用'sizeof()'而不是'strlen()'。在任何地方使用'strlen()'。我仍然無法複製這個問題... 無論如何,謝謝你的答案! – xonya