Depuis Kendall a posté un singleton threadsafe qui tente d'éviter les coûts de verrouillage, j'ai pensé que je pourrais en lancer un aussi :
#import <libkern/OSAtomic.h>
static void * volatile sharedInstance = nil;
+ (className *) sharedInstance {
while (!sharedInstance) {
className *temp = [[self alloc] init];
if(!OSAtomicCompareAndSwapPtrBarrier(0x0, temp, &sharedInstance)) {
[temp release];
}
}
return sharedInstance;
}
Ok, laissez-moi vous expliquer comment ça marche :
-
Une affaire rapide : En exécution normale sharedInstance
a déjà été défini, de sorte que le while
n'est jamais exécutée et la fonction revient après avoir simplement vérifié l'existence de la variable ;
-
Une affaire lente : Si sharedInstance
n'existe pas, une instance est allouée et copiée à l'aide d'un Compare And Swap ('CAS') ;
-
Affaire contestée : Si deux threads tentent tous deux d'appeler sharedInstance
en même temps ET sharedInstance
n'existe pas au même moment, ils initialiseront tous deux de nouvelles instances du singleton et tenteront de le CASer en position. Celui qui gagne le CAS retourne immédiatement, celui qui perd libère l'instance qu'il vient d'allouer et retourne la valeur (maintenant définie) sharedInstance
. L'unique OSAtomicCompareAndSwapPtrBarrier
agit à la fois comme une barrière d'écriture pour le thread de réglage et comme une barrière de lecture du thread de test.