Implémentation d’une bibliothèque permettant d’utiliser les objets actifs Responsables : Joël Falcou et Jean-Thierry Lapresté Présenté par : Maxence Schmitt et Romain Guidoux 22 Mars 2011
Introduction Créer une bibliothèque C++ Simplification de la gestion des threads Utilisation de bibliothèques Boost Etude des différentes solutions possibles
Plan Introduction Présentation du patron de conception « Objets Actifs » Les implémentations proposées Détail de l’implémentation réalisée Conclusion
Implémentations proposées Implémentation réalisée Les threads Un processeur n’exécute qu’un seul thread à un instant t Impression d’exécution parallèle pour l’utilisateur Patron Objets Actifs Implémentations proposées Implémentation réalisée Threads Objets Actifs Lambda Héritage Présentation File de messages Sérialisation Résultats
Implémentations proposées Implémentation réalisée Les threads en C++ Solutions disponibles : Qt : Qthread Bibliothèque POSIX : pthread Boost : Boost.Threads Patron Objets Actifs Implémentations proposées Implémentation réalisée Threads Objets Actifs Lambda Héritage Présentation File de messages Sérialisation Résultats
Les sections critiques Gestion des ressources critiques Exclusion mutuelle (mutex) using namespace std; int nb = 4; void threadWork() { if (nb % 2 == 0) cout << "Pair : " << nb << endl; else cout << "Impair : " << nb << endl; // Un traitement compliqué ici nb++; } int main(void) { try boost::thread unThread(&threadWork); unThread.join(); } catch (exception &e) {} return 0; Patron Objets Actifs Implémentations proposées Implémentation réalisée Threads Objets Actifs Lambda Héritage Présentation File de messages Sérialisation Résultats
Implémentations proposées Implémentation réalisée Les objets actifs Article d’Herbert Sutter : ”Prefer Using Active Objets Instead of Naked Threads” Rendre asynchrones des méthodes d’un objet Cacher la manipulation des threads Patron Objets Actifs Implémentations proposées Implémentation réalisée Threads Objets Actifs Lambda Héritage Présentation File de messages Sérialisation Résultats
Solution 1 : fonctions lambda Fonction sans nom définie pour un usage ponctuel Patron Objets Actifs Implémentations proposées Implémentation réalisée Threads Objets Actifs Lambda Héritage Présentation File de messages Sérialisation Résultats
Solution 1 : fonctions lambda Syntaxe utilisée par Sutter -> prochaine norme de C++ Recherches dans Boost.Lambda et Boost.Phoenix Utilisation uniquement dans les boucles for_each(v.begin(), v.end(), if_(arg1 > 5) [ cout << arg1 << ", " ] ); Patron Objets Actifs Implémentations proposées Implémentation réalisée Threads Objets Actifs Lambda Héritage Présentation File de messages Sérialisation Résultats
Implémentations proposées Implémentation réalisée Solution 2 : héritage A chaque méthode asynchrone correspond un sous-type de Message Patron Objets Actifs Implémentations proposées Implémentation réalisée Threads Objets Actifs Lambda Héritage Présentation File de messages Sérialisation Résultats
Choix de l’implémentation Utilisation des fonctions lambda impossible Solution à base d’héritage Classe Message interne à l’Active Helper Boost.Thread pour l’implémentation des threads Patron Objets Actifs Implémentations proposées Implémentation réalisée Threads Objets Actifs Lambda Héritage Présentation File de messages Sérialisation Résultats
Implémentations proposées Implémentation réalisée File de messages Boost.Interprocess Avantages FIFO Synchronisée Attente passive Patron Objets Actifs Implémentations proposées Implémentation réalisée Threads Objets Actifs Lambda Héritage Présentation File de messages Sérialisation Résultats
Implémentations proposées Implémentation réalisée File de messages File de messages système Doivent être uniques N’est pas générique Trouver une solution pour sérialiser les données Solution alternative File normale concurrente Patron Objets Actifs Implémentations proposées Implémentation réalisée Threads Objets Actifs Lambda Héritage Présentation File de messages Sérialisation Résultats
Implémentations proposées Implémentation réalisée Sérialisation Boost.Serialization Par redéfinition de méthode serialize() ou save()/load() Permet de gérer les arguments des Messages Patron Objets Actifs Implémentations proposées Implémentation réalisée Threads Objets Actifs Lambda Héritage Présentation File de messages Sérialisation Résultats
Sérialisation d’arguments Sérialisation d’un paramètre Sérialisation d’un pointeur d’objet actif void serialize(Archive& ar, const unsigned int version) { boost::serialization::base_object<Active::Message>(*this); ar & filename; } Patron Objets Actifs Implémentations proposées Implémentation réalisée Threads Objets Actifs Lambda Héritage Présentation File de messages Sérialisation Résultats
Destruction d’un objet actif Destruction de l’objet actif Destruction de l’activeHelper Exécution des messages Attente d’un message de fin Fermeture thread Patron Objets Actifs Implémentations proposées Implémentation réalisée Threads Objets Actifs Lambda Héritage Présentation File de messages Sérialisation Résultats
Implémentations proposées Implémentation réalisée Tests Tests réalisés Méthode sans paramètre Méthode avec paramètres Pointeur vers l’objet actif Plusieurs objets actifs Patron Objets Actifs Implémentations proposées Implémentation réalisée Threads Objets Actifs Lambda Héritage Présentation File de messages Sérialisation Résultats
Implémentations proposées Implémentation réalisée Résultats Les messages d’un même objet actif patientent jusqu’à leur exécution Les paramètres sont bien pris en charges Plusieurs objets actifs peuvent s’exécuter parallèlement Patron Objets Actifs Implémentations proposées Implémentation réalisée Threads Objets Actifs Lambda Héritage Présentation File de messages Sérialisation Résultats
Conclusion Objectifs atteints Implémentation d’une version fonctionnelle du patron Programme de test Documentation d’utilisation Ce qu’il reste à faire : Tests unitaires (Boost) Permettre le renvoi de résultats