9
votes

Utilisation de la classe SET_NEW_HANDLER

Pour la mise en œuvre New_Handler spécifique de classe, j'ai rencontré l'exemple suivant dans le livre "Efficace C ++". Cela ressemble à un problème dans un environnement multithread, ma question est de savoir comment réaliser une nouvelle classe spécifique à un environnement multithreadé? xxx


0 commentaires

3 Réponses :


0
votes

C ++ ne sait pas (encore) quels threads sont. Vous devrez passer à vos manuels de bibliothèque de bibliothèque / système d'exploitation de votre compilateur / C ++ et de votre bibliothèque de fil pour déterminer un moyen sûr de le faire, ou si cela est même possible. Je suggérerais que le nouveau gestionnaire devrait probablement être le même dans l'application. Ce n'est pas un mécanisme très flexible, peut-être que vos besoins seraient mieux servis avec un allocator ou peut-être une usine (fonction)? Que cherchez-vous à faire à l'intérieur du nouveau gestionnaire personnalisé?


0 commentaires

4
votes

Tu as raison. Ce n'est probablement pas le fil sûr. Vous voudrez peut-être envisager une approche alternative comme à l'aide du Nothrow code> Version code> de Nouveau code> à la place:

void* X::operator new(std::size_t sz) {
  void *p;
  while ((p = ::operator new(sz, std::nothrow) == NULL) {
    X::new_handler();
  }
  return p;
}


0 commentaires

0
votes

Peut-être que vous en regardez le mauvais sens. Je ne pense pas qu'il y ait un moyen de limiter l'ensemble de l'application de la mémoire allouée (car une grande partie de l'allocation de mémoire peut être en dehors de votre code), de sorte que la meilleure façon de le faire serait de contrôler ce que vous pouvez - c'est-à-dire la mise en œuvre du gestionnaire.

Configurez le gestionnaire pour appeler une instance d'une classe "OutofMemoryHandler" (appelez-la ce que vous voulez) au début du programme et que son comportement par défaut appelle le gestionnaire existant. Lorsque vous souhaitez ajouter une manipulation spécifique de classe, ajoutez un comportement à votre OutofMemoryHandler en utilisant vos techniques préférées C ++ pour un comportement dynamique.

Cette solution devrait bien fonctionner dans un environnement unique fileté, mais échouera dans un environnement multi-fileté. Pour que cela fonctionne dans un environnement multi-threadé, vous devez avoir l'appelant informer l'objet du gestionnaire qu'il fonctionne dans un fil particulier; Passer le fil-identifiant avec la classe serait un bon moyen de le faire. Si le gestionnaire est appelé, il vérifie le thread-ID et détermine le comportement à exécuter en fonction de la classe associée. Lorsque le nouvel appel () est terminé simplement, DERRISEGISTER L'ID de thread-ID pour assurer le comportement par défaut correct (beaucoup comme vous le faites déjà dans la réinitialisation du gestionnaire par défaut).


0 commentaires