Soyez le premier à donner votre avis sur cette source.
Vue 17 751 fois - Téléchargée 817 fois
// Librairies C++ #include<string> #include<iostream> // Librairies supplémentaires #ifdef WIN32 #include<process.h> #else #include<unistd.h> #include<pthread.h> #endif // Classe de base filament class x_Filament { public: // Constructeur x_Filament(); // Constructeur par recopie x_Filament( const x_Filament & ); /// Destructeur virtual ~x_Filament(); // Démarre le filament. void Demarrer(); // Traitement exécuté par le filament. virtual void Traitement() = 0; // Arrète le filament. void Arreter(); // Attendre la fin du filament. void Attendre(); // Etat du filament bool bExecution; private: // Filament #ifdef WIN32 static unsigned __stdcall Filament( void * pthis ); #else static void * Filament( void * pthis ); #endif // Identifiants #ifdef WIN32 HANDLE Identifiant_Filament; unsigned int Identifiant_Filament_Win32; #else pthread_t Identifiant_Filament; #endif }; // Classe derivée filament "amelioré" template< class T_CLASSE > class x_Filament_Ameliore : public x_Filament { public: // Constructeurs : l'un pour les fonctions membres normales, l'autre pour les fonctions membres 'const' x_Filament_Ameliore( T_CLASSE * c, void (T_CLASSE::*m)() ); x_Filament_Ameliore( T_CLASSE * c, void (T_CLASSE::*m)() const ); // Traitement exécuté par le filament : execute l'instruction (classe->*methode)() void Traitement(); private: // Adresses de la classe T_CLASSE * classe; // Adresse de la méthode void (T_CLASSE::*methode_normale) (); void (T_CLASSE::*methode_const) () const; // Type de méthode const bool bConst; }; template < class _CLASSE > x_Filament_Ameliore< _CLASSE >::x_Filament_Ameliore( _CLASSE * c, void(_CLASSE::*m)() ) : bConst(false) { classe = c; methode_normale = m; Demarrer(); } template < class _CLASSE > x_Filament_Ameliore< _CLASSE >::x_Filament_Ameliore( _CLASSE * c, void(_CLASSE::*m)() const ) : bConst(true) { classe = c; methode_const = m; Demarrer(); } template < class _CLASSE > void x_Filament_Ameliore<_CLASSE >::Traitement() { if( bConst ) (classe->*methode_const)(); else (classe->*methode_normale)(); } #ifdef WIN32 unsigned __stdcall x_Filament::Filament( void * pthis ) { #else void * x_Filament::Filament( void * pthis ) { #endif try { x_Filament * pParent = (x_Filament*)pthis; pParent->bExecution = true; pParent->Traitement(); } catch(...) { } #ifdef WIN32 return(0); //_endthreadex(0); #else pthread_exit(0); #endif } x_Filament::x_Filament() : bExecution( false ) { } x_Filament::~x_Filament() { if( bExecution ) { #ifdef WIN32 int resultat; resultat = CloseHandle( Identifiant_Filament ); if( resultat == 0 ) std::cout << std::endl << "Erreur avec CloseHandle()! Error = " << GetLastError() << "." << std::endl; #else pthread_detach( Identifiant_Filament ); #endif } } void x_Filament::Demarrer() { if( !bExecution ) { #ifdef WIN32 Identifiant_Filament = (HANDLE)_beginthreadex( NULL, 0, &Filament, this, 0, &Identifiant_Filament_Win32 ); if( Identifiant_Filament == 0 ) std::cout << std::endl << "Erreur avec _beginthread()!" << std::endl; #else int valeur = pthread_create( &Identifiant_Filament, 0, Filament, this ); if( valeur != 0 ) std::cout << std::endl << "Erreur avec pthread_create()!" << std::endl; #endif } } void x_Filament::Arreter() { if( bExecution ) { #ifdef WIN32 TerminateThread( Identifiant_Filament, 0 ); #else pthread_cancel( Identifiant_Filament ); #endif bExecution = false; } } void x_Filament::Attendre() { if( bExecution ) { #ifdef WIN32 int resultat; resultat = WaitForSingleObject( Identifiant_Filament, INFINITE ); if( resultat != WAIT_OBJECT_0 ) std::cout << std::endl << "Erreur avec WaitForSingleObject()! Error = " << GetLastError() << "." << std::endl; resultat = CloseHandle( Identifiant_Filament ); if( resultat == 0 ) std::cout << std::endl << "Erreur avec CloseHandle()! Error = " << GetLastError() << "." << std::endl; #else if( pthread_join( Identifiant_Filament, NULL ) != 0 ) std::cout << std::endl << "Erreur avec pthread_join()!" << std::endl; #endif bExecution = false; } }
10 avril 2010 à 19:28
7 avril 2010 à 23:06
7 avril 2010 à 20:42
Merci
14 mars 2010 à 17:17
Merci pour la source ça vas me servir. Je suis d'accord avec toi ; c'est intéressant d'avoir un objet thread.
J'ai une petite remarque :
Le programme de test lève une exception après : "Demande d'arrêt du compteur numéro 3".
J'ai essayé de mettre : monTemps3.Attendre(); après l'arrêt mais sans succès.
J'ai du remplacer un bout de code pour que ça marche : (je me suis passé des exceptions)
#ifdef WIN32
unsigned __stdcall x_Filament::Filament( void * pthis ) {
#else
void * x_Filament::Filament( void * pthis ) {
#endif
//try
if(pthis!=NULL){
x_Filament * pParent = (x_Filament*)pthis;
pParent->bExecution = true;
pParent->Traitement();
}
//catch(...)
//{
//}
#ifdef WIN32
return(0);
//_endthreadex(0);
#else
pthread_exit(0);
#endif
}
Sinon, sais tu combien de thread peux t-on créer dans un soft ?
Pour info la sortie de g++ -v :
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.1-4ubuntu9' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9)
10 mars 2010 à 04:07
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.