Dans certains milieu, traiter toutes les exceptions possible n'est pas envisageable. Voir n'en traiter aucune et tout faire crashé car il considère que c'est un évènement trop grave pour continuer (Jeu vidéo). Traiter l'exception de close dans le destructeur d'un RAII relève d'une chose futile puisque si il est correctement fait, cela devras être traiter au l'ouverture et non a la fermeture. Si tu le traite tu reviens à faire : "Oh , une exception! Bas c'est pas grave le fichier n'est pas ouvert."![]()
J'ai bien précisé : si l'ont veut les traiter, et ceci depuis mon premier message. (si le traitement du destructeur suffit c'est très bien, ie ne rien faire)
D'autre part si le fichier n'est pas ouvert ca ne lance pas d'exception. Ce qui peut lancer des exceptions ce sont les opérations qui termine les opérations sur le fichier avant de le fermer.
A noter qu'en cas d'exception le fichier est quand même fermer, mais un exception indique quand même bien que quelque chose s'est mal passé, information qui peut être utile si les données du fichier sont importantes.
Quand à traiter les exception dans le destructeur d'une classe RAII-sante, si les opérations du destructeur peuvent lancer des excpetions tu as pas le choix de les récupérer, et d'en faire quelque chose (rien, traitement, crash, autre), un destructeur ne doit jamais lancer d'exception.(bon d'accord, les ignoré ce n'est pas vraiment un traitement, n'empêche qu'il ne faut pas oublier de le faire)
Enfaite il faudrait appeler ce post le post DEBAT![]()
Cela dépend des architectures, mais dans la plupart des cas, "lent" est équivalent à "négligeable". A moins de faire du vrai temps réel ou quelque chose de critique en performance.
Pour les benchs, j'ai trouvé ça (c'est un papier qui explique les avantages du double-checked locking, donc s'il est biaisé ce serait plutôt dans l'autre sens) :
http://www.cs.wustl.edu/~schmidt/PDF/DC-Locking.pdf
Il y a certes un facteur 15 (rien d'étonnant à ça), mais on parle bien de 4µs pour prendre et releaser le mutex. Négligeable dans la plupart des cas
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 Singleton Mutex Double- ACE Implementation Checked real time (secs) 442.64 30.22 30.88 user time (secs) 441.47 30.12 30.86 time per call (usecs) 4.43 0.30 0.31 system time (secs) 0 0 0.
Le problème, c'est que ton objet n'est pas tout seul dans son coin, il dépend aussi d'un contexte système. Et ce n'est pas parce que l'ouverture de ton fichier s'est parfaitement bien passée que la fermeture se passera bien (exemple : à la fermeture, j'ai besoin de finaliser l'écriture de mon buffer, je me prends une erreur disk-full...). Le RAII est bien pour les objets qui ne dépendent pas d'un contexte extérieur, pour les autres il montre des limites.
Ok mais ça ce fera au moment de l'écriture après chaque flush, pas de la fermeture, donc pas dans le destructeur (Il n'y as pas de raison d'avoir un flush dans le destructeur ou autre que le close)à la fermeture, j'ai besoin de finaliser l'écriture de mon buffer, je me prends une erreur disk-full
Il y a une raison, c'est qu'on ne flushe pas à chaque écriture, et que l'appel de flush n'est pas obligatoire. Donc quand je ferme, je suis obligé de regarder si je n'ai pas des données en attente de flush.
Un autre exemple où la fermeture de fichier peut foirer : je lit un fichier à travers le réseau, avant ma fermeture la connexion réseau tombe : je ne peux plus fermer le fichier. Ce cas peut-être problématique ou pas (dépend de la politique du système de partage de fichiers).
RAII fonctionne bien, RFID fonctionne bien si le F est sûr de réussir, où que les conséquences de son échec sont acceptables. Il faut le garder en tête quand on fait du RAII.
Il me semblait que le double lock était en fait non thread safe, parce que il etait possible que l'assignation pouvait être effectuée avant que le constructeur soit appelé d'òu un crash si un autre thread y accède entre les deux.
Il n'y a rien d'autre que close dans le destructeur (à vérifier quand même), mais c'est dans close qu'il y a d'autre opérations que simplement tester si le fichiers est ouvert, et ces opérations peuvent lancer des excpetions (opérations de finalisation du fichier avant fermeture). D'où le besoin de le faire explicitement si l'on veut s'assurer que la fermeture c'est totalement bien passé.
Le problème du DCLP est bien l'ordre entre l'assignation et l'allocation, et le fait qu'il n'existe pas de méthode portable pour palier à ce problème. (cf un article de Meyers et Alexandrescu paru au ddj)
@white_tentacle: Très intéresent le bench. Et je suis d'accord que si il n'y a pas besoin d'un accés rapide, alors locker à chaque peut être très bien (cas d'un journal d'erreur géré par un singleton). Mais pas dans tout les cas, exemple, un allocateur mémoire pour les petits objets basé sur un singleton (genre Loki::SmallObject), un facteur de 15 n'est pas acceptable (j'ai pas de bench mais ca doit compenser le temps gagner par rapport à une allocation classique).
C'est comme pour ce qui concerne la gestion de la destruction et de la création, ca dépend de l'objectif recherché.
Partager