C++ En C++26 , la bibliothèque standard C++ introduit un nouvel en-tête <hive> contenant la structure de données `List<List<Object>` std::hive , qui implémente essentiellement u...
Worldlex WikiFrancaisLecture gratuite
C++
En C++26 , la bibliothèque standard C++ introduit un nouvel en-tête <hive>contenant la structure de données `List<List<Object>` std::hive, qui implémente essentiellement un pool d'objets. Il s'agit d'une collection qui réutilise la mémoire des éléments effacés. Elle inclut également une classe std::hive_limitsfournissant des informations de disposition sur les limites de capacité des blocs. std::hive est basée sur la classe plf::colonyde la plfbibliothèque.
Dans la bibliothèque de classes de base .NET , certains objets implémentent ce modèle. System.Threading.ThreadPoolest configuré pour allouer un nombre prédéfini de threads. Une fois libérés, ces threads sont disponibles pour un autre calcul. Ainsi, il est possible d'utiliser des threads sans supporter le coût de leur création et de leur libération.
Le code suivant illustre l'implémentation en C# du patron de conception de pool d'objets. Le pool est représenté par une classe statique, car il est rare d'avoir besoin de plusieurs pools. Cependant, l'utilisation de classes d'instance est tout aussi acceptable.
espace de noms Wikipedia.Exemples ;using System ; using System.Collections.Generic ;// La classe PooledObject est le type coûteux ou lent à instancier, // ou dont la disponibilité est limitée, et qui doit donc être conservé dans le pool d'objets. public class PooledObject { private DateTime _createdAt = DateTime . Now ;public DateTime CreatedAt => _createdAt ;public string TempData { get ; set ; } }// La classe Pool contrôle l'accès aux objets mis en pool. Elle maintient une liste des objets disponibles et une // collection des objets obtenus du pool et en cours d'utilisation. Le pool garantit que les objets libérés // sont retournés dans un état approprié, prêts à être réutilisés. public static class Pool { private static List < PooledObject > _available = new (); private static List < PooledObject > _inUse = new ();public static PooledObject GetObject ( ) { lock ( _available ) { if ( _available.Count ! = 0 ) { PooledObject po = _available [ 0 ] ; _inUse.Add ( po ) ; _available.RemoveAt ( 0 ) ; return po ; } else { PooledObject po = new ( ) ; _inUse.Add ( po ) ; return po ; } } }public static void ReleaseObject ( PooledObject po ) { CleanUp ( po );verrouiller ( _disponible ) { _disponible . Ajouter ( po ); _enUtilisation . Supprimer ( po ); } }private static void CleanUp ( PooledObject po ) { po . TempData = null ; } }
Dans le code ci-dessus, l'objet PooledObject possède des propriétés relatives à sa date de création, ainsi qu'une autre, modifiable par le client, qui est réinitialisée lorsque l'objet PooledObject est remis dans le pool. Le code illustre le processus de nettoyage lors de la libération d'un objet, garantissant ainsi son état valide avant qu'il puisse être de nouveau demandé au pool.
Aller
Le code Go suivant initialise un pool de ressources d'une taille spécifiée (initialisation concurrente) pour éviter les problèmes de concurrence de ressources via les canaux, et dans le cas d'un pool vide, configure le traitement du délai d'attente pour empêcher les clients d'attendre trop longtemps.
// pool de packages pool de packagesimport ( "erreurs" "log" "math/rand" "sync" "time" )const getResMaxTime = 3 * time.Secondvar ( ErrPoolNotExist = errors . New ( "pool not exist" ) ErrGetResTimeout = errors . New ( "get resource time out" ) )// Type de ressource Resource struct { resId int }// NewResource Simule la création d'une ressource initiale lente // (par exemple, la connexion TCP, l'acquisition d'une clé symétrique SSL et l'authentification prennent du temps) func NewResource ( id int ) * Resource { time . Sleep ( 500 * time . Millisecond ) return & Resource { resId : id } }// Les ressources de simulation consomment du temps et leur consommation aléatoire est de 0 à 400 ms. func ( r * Resource ) Do ( workId int ) { time . Sleep ( time . Duration ( rand . Intn ( 5 )) * 100 * time . Millisecond ) log . Printf ( "Utilisation de la ressource n° %d, tâche terminée %d " , r . resId , workId ) }// Pool basé sur l'implémentation de canaux Go, pour éviter les problèmes d'état de concurrence des ressources. Type Pool chan * Ressource// Créer un pool de ressources de la taille spécifiée // Les ressources sont créées simultanément pour gagner du temps d'initialisation func New ( size int ) Pool { p : = make ( Pool , size ) wg := new ( sync.WaitGroup ) wg.Add ( size ) for i := 0 ; i < size ; i ++ { go func ( resId int ) { p < - NewResource ( resId ) wg.Done ( ) } ( i ) } wg.Wait ( ) return p }// GetResource basé sur le canal, l'état de concurrence des ressources est évité et un délai d'acquisition de ressource est défini pour un pool vide func ( p Pool ) GetResource () ( r * Resource , err error ) { select { case r := <- p : return r , nil case <- time . After ( getResMaxTime ): return nil , ErrGetResTimeout } }// GiveBackResource renvoie des ressources au pool de ressources func ( p Pool ) GiveBackResource ( r * Resource ) error { if p == nil { return ErrPoolNotExist } p <- r return nil }// paquet principal paquet principalimport ( "github.com/tkstorm/go-design/creational/object-pool/pool" "log" "sync" )func main () { // Initialiser un pool de cinq ressources, // qui peut être ajusté à 1 ou 10 pour observer la différence size : = 5 p : = pool.New ( size )// Invoque une ressource pour effectuer la tâche id doWork := func ( workId int , wg * sync . WaitGroup ) { defer wg . Done () // Récupère la ressource du pool de ressources res , err := p . GetResource () if err != nil { log . Println ( err ) return } // Ressources à retourner defer p . GiveBackResource ( res ) // Utilise les ressources pour traiter la tâche res . Do ( workId ) }// Simuler 100 processus concurrents pour obtenir des ressources du pool d'actifs num := 100 wg := new ( sync . WaitGroup ) wg . Add ( num ) for i := 0 ; i < num ; i ++ { go doWork ( i , wg ) } wg . Wait () }
Java
Java prend en charge le pooling de threads via java.util.concurrent.ExecutorServicedes classes associées. Le service d'exécution dispose d'un certain nombre de threads « de base » qui ne sont jamais supprimés. Si tous les threads sont occupés, le service alloue le nombre autorisé de threads supplémentaires, qui seront supprimés s'ils ne sont pas utilisés pendant une durée déterminée. Si le nombre de threads disponibles est insuffisant, les tâches peuvent être placées dans une file d'attente. Enfin, si cette file d'attente risque de devenir trop longue, il est possible de configurer le service pour suspendre le thread demandeur.