(Courriels de diversion: <rougirent@consonance-recyclages.com> <faible@escrimeurs-retrocederai.com> <repeteraient@sous-paient-deracina.com> <intercedant@intra-communautaire-escarcelles.com> <mercantis@pleut-apraxie.com> <greveras@braviez-eduques.com> <oursins@coordonnatrice-degazer.com> <directes@calculerions-antidater.com> <reserve@broutais-jonglerons.com> <resquilleuses@proletarisation-reinvestissions.com> )


Je vous transmet le résultat du thread que j'ai eu avec Stéphane PION qui m'a 
donné une réponse plus que satisfaisante ;-)

----------  Message transmis  ----------
Subject: Re: [linux-31] cluster et gcc
Date: Mon, 14 May 2001 16:51:54 +0200
From: PION_Stephane@stna.dgac.frTo: tribo@anfora.fr

Thomas RIBO wrote:
> Ben oui, mais d'après mes tests, c'est pas terrible (bizarrement ;-).
> En fait, je faisais une sorte de binding C++ :
> class Threads
> {
>         pthread_t* leThread;
>         Thread()
>         {
>                 if(!pthread_create(&this->leThread,
>                                 &attribut,
>                                 Thread::demarrer,
>                                 this))
>                         cout << "Creation du thread" << endl;
>                 else
>                         throw Exception("Echec de la creation du thread");
>         }
>
>         static void* demarrer(void* thread)
>         {
>                 ((Thread*)thread)->traitement();
>                 return 0;
>         }
>
>         virtual void traitement();
> }
>
> Et pour s'en servir, il suffit d'heriter de Thread et d'implementer la
> fonction traitement.
> Le problème, c'est que sous linux, le pointeur envoyé en paramètre à
> demarrer par pthread_create n'est pas valide, alors que sous Solaris, je
> n'ai pas le problème...
>
> Autre problème, aléatoire, j'ai un "pure virtual method called" de temps en
> temps quand je crée un thread, alors que je l'appelle depuis un fils de
> Thread dont la méthode traitement est bien implémentée (c'est la seule
> virtuelle pure). Si tu as une idée...

Bon, j'ai quelques commentaires, quelques solutions et un pointeur.

D'abord, l'utilisation directe en C++ de l'API POSIX C n'est pas, à mon
avis une bonne idée. L'utilisation de méthode statique n'est pas
géniale. Mais j'y reviendrais plus tard.

Pour le "pure virtual method called", le problème vient de la norme C++.
Tu devrais avoir systématiquement ce type de message.

Quand tu construit la classe dérivée, le constructeur de la classe
parente sera appelé AVANT l'entrée dans le constructeur de la classe
dérivée. On va dire qu'elle n'a donc pas d'existance "légale" . Comme
dans ton constructeur, tu tente d'appeler une une méthode de la classe
dérivée qui n'existe pas encore, ça fait boom. Ou ça devrait. Donc, si
ton compilateur fait les choses proprement, il est normal que tu ais ce
message.

Au niveau du pointeur non valide. Dans le code ci dessus, pthread_create
va jardiner dans la mémoire. Ton pointeur n'est pas initialisé. Alors ça
passe sur Solaris, c'est un heureux (malheureux) hasard. Peu de
fonctions prennent en charge l'allocation d'un pointeur.

J'ai réécris ce morceau de code. C'est pas super propre, même un peu
sale, mais ça marche
#include <pthread.h>
#include <iostream>
#include <unistd.h>

class Threads
{
private:
  pthread_t leThread;
public:
        Threads()
        {

        }
  pthread_t* init()
  {
    if(!pthread_create(&(this->leThread),
		       NULL,
		       Threads::demarrer,
		       static_cast<void *>(this)))
      {
	cout << "Creation du thread" << endl;
	return &(this->leThread);
      }
    else
      {
	cout << "Echec de la creation du thread" << endl;
	exit(0);
      }
  }

        static void* demarrer(void* thread)
        {
	  static_cast<Threads *>(thread)->traitement();
	  pthread_exit(0);
        }

        virtual void traitement() = 0;
};


class Derive : public Threads
{
public:
  virtual void traitement() {cout << "traitement" << endl; }
};


int main(int argc, char **argv)
{
  Derive toto;
  pthread_t * join_to = toto.init();
  pthread_join(*join_to,NULL);
  exit(0);
}


qui se compile avec c++ -g threads.cc -o t_thread -lpthread

!! cout n'est à priori pas thread safe


Comme je ne te conseillais pas d'utiliser directement l'API POSIX en
C++, j'ai évidement une solution de rechange. C'est énorme, mais ça vaut
vraiment le coup. Ce monstre, c'est ACE (Adaptative Communication
Environnement).
La page d'accueil
http://www.cs.wustl.edu/~schmidt/ (je crois qu'il faut faire une
offrande quand on voit ce monsieur)
Le tutorial (une mine d'or)
Il y a en particulier deux chapitres qui t'interesseront sans doute au
plus haut point. (chapitres 4 et 5)
http://www.cs.wustl.edu/~schmidt/PDF/ACE-tutorial.pdf
les sources
http://www.cs.wustl.edu/~schmidt/ACE_wrappers

ACE est un framework C++ orienté communication. C'est compilable sur à
peu près tout ce qui bouge, et c'est super efficace. Le revers de la
médaille, c'est que c'est un peu dur à prendre en main. Mais, il y a des
kilos de documentation dans le répertoire PDF, et plein de tutoriaux en
ligne
(http://www.cs.wustl.edu/~schmidt/ACE_wrappers/docs/ACE-tutorials.html)

Il propose, en particulier une API C++ permettant de faire des
applications multithread. Ce n'est pas un aspect que j'utilise, mais si
tu décide d'utiliser ACE, je peux t'aiguiller.

L'appli que je développe est monothread, et basée sur le démultiplexeur
d'évènement d'ACE  (#select|poll) qui permet de gérer timers, ES
réseaux, signaux unix, notifications ...

J'utilise aussi les files de messages, et puis quelques classes utiles
qui permettent de tracer un programme, d'activer des timers pour mesurer
des temps de traversée de code, ...

Il y a aussi des surcouches à new et delete qui permettent plein de
trucs (comme garantir un temps d'exécution)
...

Bon courage
Stéphane
--
au lieu de mettre en joue quelque vague ennemi, mieux vaut attendre un
peu
qu'on le change en ami (Georges Brassens)

-------------------------------------------------------

-- 
Thomas RIBO
tribo@anfora.frAnfora -- Revenir aux sources...

---------------------------------------------------------------------
Aide sur la liste: <URL:mailto:linux-31-help@CULTe.org>Le CULTe sur le web: <URL:http://www.CULTe.org/>