Atomic est-il thread safe?
NiClou
Membre
Hello,
Je reviens avec mon lot de question qui va faire de ce topic un topic sur 8 pages xd
J'avais une question sur le nonatomic et plus précisément sur atomic.
Considérons la classe suivante (à peu près):
@interface myClass ()
@property (atomic, retain) NSMutableArray *myArray;
@property (nonatomic) dispatch_queue_t queue;
@end
@implementation myClass
- (instancetype)init {
if ((self = [super init])) {
self.myArray = [NSMutableArray arrayWithCapacity:100];
// Create queue
self.queue = dispatch_queue_create("com.myQueue.request-queue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t lowQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_set_target_queue(self.queue, lowQueue);
}
return self;
}
Est ce que le fait de mettre myArray en atomic et de set une queue suffit à "proteger" myArray?
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Réponse rapide: utiliser atomic va placer un verrou (lock) au début des accesseurs et le retirer à la fin.
C'est ce qui rend l'opération atomique (= d'un seul tenant). Un autre thread devra donc attendre la fin de l'accès pour accéder à la propriété.
Cela dit, cela ne suffit pas à rendre le programme thread safe: en effet, d'autres problèmes peuvent subvenir, notamment d'interblocage.
Ok, mais tous les accesseurs à cette propriété sont fait dans cette même classe.
En toute théorie, ça ne devrait pas poser de problèmes. Si?
Si par exemple plus tard tu itères sur cet array, le fait que le getter / la propriété soit atomique ne suffira pas pour autant à rendre ton code thread-safe : Par exemple ce code n'est pas thread-safe, car l'accès à myArray est peut-être atomic quand tu exécutes self.myArray, mais rien ne garantit que pendant l'itération de ton tableau, il n'y ait pas un autre thread qui accède à ton self.myArray lui aussi, et change son contenu, genre : Et dans ce cas si ce code removeAllObject qui s'exécuterait dans un autre thread s'exécute en plein pendant que ton thread 1 itère sur ton tableau de l'autre côté, badaboum...
Donc mettre "atomic" garantit l'atomicité de l'accesseur (getter/setter) mais ça ne garantit pas que ton code soit thread-safe quand tu utilises la propriété pour autant, car garantir la thread-safety c'est quand même un peu + que juste mettre un "atomic".
Plus exactement, l'atomicité est implémentée avec un "spin lock"
https://github.com/opensource-apple/objc4/blob/master/runtime/Accessors.subproj/objc-accessors.mm#L104