PDA

Visualizza la versione completa : GTK e software multithread


nik600
13-05-2006, 11:16
ciao

sto facendo un software multithread in ambiente unix, in c e con gtk per la grafica.

il software ha diversi thread in esecuzione, diciamo 3/4 e tutti vanno ad aggiornare graficamente diversi componenti di una finestra, (frame, bottoni, ecc ecc)

ho aggiunto da poco una funzione, che si occupa di gestire il logging delle informazioni in una textarea



void log_window(char *mex,int mex_log_level, ...){

/*
qui andrÓ messo il controllo sul livello di logging
*/
if(mex_log_level<=log_level){

//per evitare problemi metto un semaforo per l'accesso a questa risorsa
sem_wait(&sem_logging);

va_list ap;
int d;
char c, *p, *s;

va_start(ap, mex);
while (*mex)
switch(*mex++) {
case 's': /* string */
s = va_arg(ap, char *);
gtk_text_insert(textarea_log, NULL, NULL,NULL, s, -1);
break;
case 'd': /* int */
d = va_arg(ap, int);
char str[33];
sprintf(str,"%d",d);
gtk_text_insert(textarea_log, NULL, NULL,NULL, str, -1);
break;
case 'c': /* char */
/* need a cast here since va_arg only
takes fully promoted types */
c = (char) va_arg(ap, int);
printf("char %c\n", c);
break;
}
va_end(ap);

//libero la risorsa
sem_post(&sem_logging);

}else{
return ;
}

}


il problema Ŕ che dopo alcuni messaggi di logging ottengo questo errore, e l'applicazione si blocca:



Xlib: unexpected async reply (sequence 0x839)!


:-( secondo voi, cosa posso fare ? temo che, nonostante io abbia messu un semaforo nella funzione, questo semaforo non tenga conto di quando il main loop delle gtk va a lavorare sulla textarea... o sbaglio?

grazie

nik600
17-05-2006, 10:28
l'applicazione main deve essere strutturata in questo modo



int
main (int argc, char *argv[])
{
GtkWidget *window;

/* init threads */
g_thread_init(NULL);
gdk_threads_init();

/* init gtk */
gtk_init(&argc, &argv);

window = create_window();
gtk_widget_show(window);

gdk_threads_enter();
gtk_main();
gdk_threads_leave();

return 0;
}



prima e dopo aver chiamato (da parte di thread) eventi che modificano qualche evento delle GTK




gdk_threads_enter();
/*evento che modifica le GTK*/
gdk_threads_leave();

Loading