Newsgroup: it.comp.os.linux.development
Titolo: GTK e i threads (Nemo Capitani leggi)

Descrizione del problema:
Supponiamo di avere un'applicazione GTK nella quale c'e' un pulsante 
che una volto premuto lancia una funzione moooolto pesante e lunga, 
tipicamente perche' ce' un lungo loop, mentre questa funzione gira il
pulsante rimarra' premuto e il form principale non verra' piu' 
aggiornato.
Soluzione1:
usare i thread, e quindi generare un nuovo thread alla pressione del
pulsante. Bello nella pratica ma da panico nella realta', far convivere
GTK e i thread e' una cosa che va oltre le mie conoscenze.
Soluzione2:
Supposto che la funzione richiamata dal pulsante sia del tipo
gint funzione()
{ 
 while(bo)
  {
   do_stuff;
  }
}
Modificarla nel modo seguente
gint funzione()
{
 while (bo)
  {
   do_stuff;
   while (gtk_events_pending()) //queste due istruzuioni ridaranno
momentaneamente
        gtk_main_iteration();   //il controllo al main 
  }
}
Questo post vuole essere il riassunto delle mie esperienze di questi 
giorni cercando di usare i thread in un'applicazione GTK .
Nel subject mi sono riferito a Nemo Capitani perche' anche lui aveva
avuto lo stesso problema, cmq non e' un post privato, spero possa
aiutare
anche qualcun'altro.
-- 
  _  _  >>Now at work<<  _     || ICQ number.................Non lo uso
 | \| |___ _____ ___ ___|_|___ || Home-Page ................Non ce l'ho
 | .` | -_|     | -_|_ -| |_ -||| E-Mail................Non l'avrai mai
 |_|\_|___|_|_|_|___|___|_|___||| Un Nemesis che ha pochi e-contatti ;)

 }
Bene, io ho un programma con molti thread e interfaccia GTK-- (ma penso che
con le GTK+ sia simile)
Il problema e' che l'interfaccia va' in freeze se richiamo delle funzioni di
aggiornamento dell'interfaccia
all'interno di thread...
sara' lo stesso?
--
---
Alessandro >>CoMiX<< Cominu
e-mail: 
aco...@tiscalinet.it
Icq: 116354077
Linux User # 203765
[That's not a bug, that's a feature..]

 sara' lo stesso?
Non ti saprei rispondere, perche' come ho detto sopra, far convivere
GTK e threads e' fuori dalla mia attuale portata.
Cmq se ti puo' essere d'aiuto, io nelle mie prove alla pressione del
tasto creavo un nuovo thread passandogli una funzione che doveva essere
eseguita, in questa funzione c'erano anche delle istruzioni che ridise-
gnavano alcuni particolari dell'interfaccia principale, e mi sono
accorto
che sulla console compariva la scritta 
Xlib: unexpected async reply( sequence...)
A questo punto il programma si freezava, anche se non andava in crash,
infatti cliccando un po' a caso sull'interfaccia si riprendeva.
Molto probabilmente c'e' un problema di sincronizzazione nell'accesso
alle risorse, e mi e' stato spiegato che e' bene fare in modo che solo
il thread principale posso scrivere sul main form, se gli altri thread 
proprio devono farlo bisogno cmq delegare questo compito al main 
istruendolo sul quando farlo con dei segnali.
Morale della favola, se puoi evita che i thread che non siano il 
principale abbiano accesso all'interfaccia, se non puoi prova a chiedere
su comp.programming.threads che sicuramente ci trovi gente piu' 
informata ;)


 informata ;)
esatto si comporta allo stesso modo, pero' non scrive nulla sulla console...
Grazie comunque!


 Grazie comunque!
Figurati :)


 }
yesss: eccolo qui. Bravo
-- 
Nato nel vizio, morto nel supplizio
Nato nel peccato, ad entrare sia invitato

all'interno di thread...
Semplice: significa che GTK non è thread safe, se cammina con un piede 
solo tutto ok, se inizia a usarne due cominciano a pestarsi a vicenda. 
Non è una cosa così orribile, nemmeno VCL lo è, ma VCL ha il metodo 
TThread::Synchronize, ossia una parte dell'oggetto TThread che viene 
eseguita non nel thread extra rappresentato dall'oggetto, ma nel thread 
principale. Puoi fare una cosa del genere con una queue e un semaforo: 
metti nella queue le operazioni da svolgere (magari puntatori a 
funzioni), usando il semaforo per sincronizzare l'accesso alla stessa. 
In pseudocodice:
// interno del main loop
entra in possesso del semaforo
peek della coda
se coda non nulla:
 dequeue
 esegui operazione
rilascia il semaforo
torna all'inizio
// thread a parte
se c'è bisogno di interagire con l'interfaccia:
 entra in possesso del semaforo
 enqueue del puntatore alla procedura da eseguire
 rilascia il semaforo
eccetera
