(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/>