Forum Programmation.c++ glib::2 threads en parallele, pb de synchro...

Posté par  .
Étiquettes : aucune
0
8
mai
2005

Alors voila: je dois faire une simulation de termites...donc elle doivent gigoter dans tous les sens et pendant ce temps je dois faire des captures. donc je fais deux threads et la bim:
-----------------------------------
Xlib: unexpected async reply (sequence 0x703)!
Processus arrêté
----------------------------------

Voila le code(on m'a parlé de la classe dispatcher mais j'y comprends pas grand chose a vrai dire)

Constructeur:
---------------------------------------------------------------------------------
Gtk::Button *play;
Gtk::Button *pause;
Gtk::ToggleButton *rec;

Glib::Thread * t;
Glib::Thread * t1;
Glib::Mutex *mutex;
Glib::Mutex *mutex1;

play->signal_clicked().connect(sigc::mem_fun(*this, &Fenetre::joue));
pause->signal_clicked().connect(sigc::mem_fun(*this, &Fenetre::paus));
rec->signal_toggled().connect(sigc::mem_fun(*this, &Fenetre::enreg_pas_simul));

if(!Glib::thread_supported()) {
Glib::thread_init();
}

mutex = new Glib::Mutex();
mutex1 = new Glib::Mutex();
mutex->lock();
mutex1->lock();

t = Glib::Thread::create(sigc::mem_fun(*this,&Fenetre::go), true);
t1 = Glib::Thread::create(sigc::mem_fun(*this,&Fenetre::go_enreg), true);
----------------------------------------------------------------------------------


void Fenetre::go(){
while(true){
mutex->lock();
mutex->unlock();
queue_draw();
maBelleGrille->avanceLesTermitesDuneCase();
}
}

void Fenetre::go_enreg(){

const Glib::RefPtr<Gdk::Colormap> cmap = colormap;
const Glib::RefPtr<Gdk::Drawable> windrawable = win;

Glib::RefPtr<Gdk::Pixbuf> pixbuffer;

while(true){
mutex1->lock();
mutex1->unlock();
cout << "prout" << endl;
pixbuffer = Gdk::Pixbuf::create(windrawable,cmap,
0,0,0,0, tailleCaseX*maBelleGrille->get_hauteur(),
tailleCaseY*maBelleGrille->get_largeur());
st << "captures/";
st << i;
st << ".png";
pixbuffer->save(st.str(),"png");
i++;
usleep(CSLEEP);
st.str("");
}
}

void Fenetre::joue(){
adTerm->set_sensitive(false);
adCopo->set_sensitive(false);
rmEntite->set_sensitive(false);
mutex->unlock();
}

void Fenetre::paus(){
adTerm->set_sensitive(true);
adCopo->set_sensitive(true);
rmEntite->set_sensitive(true);
mutex->trylock();
}

void Fenetre::enreg_pas_simul(){
if(rec->get_active())
mutex1->unlock();
else
mutex1->trylock();
}
  • # Only one thread can use GTK+

    Posté par  . Évalué à 1.

    Je n'ai pas vérifié ton code, mais ton pbm est très classique. Pour plus d'info, voir : http://www.gtk.org/api/2.6/gdk/gdk-Threads.html(...)
    GTK+ is "thread aware" but not thread safe — it provides a global lock controlled by gdk_threads_enter()/gdk_threads_leave() which protects all use of GTK+. That is, only one thread can use GTK+ at any given time.
    • [^] # Re: Only one thread can use GTK+

      Posté par  . Évalué à 1.

      Salut,

      d'abord merci de t'y intéresser..

      mais j'utilise les threads de la Glib... donc si tu es coutumier de la glib je suis preneur
      • [^] # Re: Only one thread can use GTK+

        Posté par  . Évalué à 1.

        Hmm, les threads et la Xlib (utilisés par GTK) est un coktail assez explosif. Tu as intérêt à savoir ce que tu fais avant de toucher à ta fenêtre. Pour info, la connexion avec le serveur X est un descripteur de fichier, tout ce qu'il y a de plus banal (socket unix locale).

        Maintenant si tu t'amuses à faire des mises à jour dans chaque thread de ton interface, les paquets Xlib (XDrawText, XCopyArea, etc...) risque de s'emméler et foutre complètement en l'air le protocole.

        Deux façon de faire, d'abord la casse gueule :
        - Tu fais tes mises à jour n'importe quel thread, en faisant attention d'encadrer CHAQUE appel à gtk/X11/gdk par un appel à mutex, je lancerais aussi un XFlush() avant.

        Plus propre :
        - Un et un seul thread s'occupe de gérer l'affichage, synchronisé avec une classe qui va bien (mutex, pipe, & co).

        En tous les cas l'erreur que tu as reçu de la Xlib est typiquement le reflet d'un problème de paquets entremélés.

        Ah, les joies de la programmtion multi-threadé en environnement X11 ....
  • # hummm

    Posté par  (site web personnel) . Évalué à 2.

    ouais, pb de synchro entre threads, comme le commentaire plus haut. moi je retiens :
    cout << "prout" << endl;
    je vois qu'on a les mêmes méthodes de débugages en cas de prises de têtes :-)

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.