2011-01-14 19 views
5

Le proprietà Objective-C sono impostate su atomic, che garantisce che gli accessor siano atomici ma non garantiscono la sicurezza generale del thread (come da this question). La mia domanda è, non sono ridondanti le proprietà atomiche nella maggior parte degli scenari di concorrenza? Ad esempio:In quali circostanze sono utili le proprietà atomiche?

Scenario 1: proprietà mutabili

@interface ScaryMutableObject : NSObject {} 

@property (atomic, readwrite) NSMutableArray *stuff; 

@end 

void doStuffWith(ScaryMutableObject *obj) { 
    [_someLock lock]; 
    [obj.stuff addObject:something]; //the atomic getter is completely redundant and could hurt performance 
    [_someLock unlock]; 
} 

//or, alternatively 
void doStuffWith(ScaryMutableObject *obj) { 
    NSMutableArray *cachedStuff = obj.stuff; //the atomic getter isn't redundant 
    [_someLock lock]; 
    [cachedStuff addObject:something]; //but is this any more performant than using a nonatomic accessor within the lock? 
    [_someLock unlock]; 
} 

Scenario 2: proprietà immutabili

stavo pensando che forse proprietà atomiche sarebbe utile per evitare blocchi quando si lavora con oggetti immutabili , ma poiché gli oggetti immutabili possono puntare a oggetti mutabili in Objective-C, questo non è di grande aiuto:

@interface SlightlySaferObject : NSObject {} 

@property (atomic, readwrite) NSArray *stuff; 

@end 

void doStuffWith(SlightlySaferObject *obj) { 
    [[obj.stuff objectAtIndex:0] mutateLikeCrazy];//not at all thread-safe without a lock 
} 

Gli unici scenari che posso pensare dove è sicuro da usare di accesso atomiche senza serratura (e quindi vale la pena utilizzare proprietà atomiche a tutti) sono:

  1. Lavorare con proprietà che sono primitivi;
  2. Lavorare con proprietà che sono garantiti per essere immutabile e non per puntare a oggetti mutabili (come un NSString o un NSArray di oggetti immutabili).

Mi manca qualcosa? Ci sono altri buoni motivi per usare le proprietà atomiche?

+1

Credo che l'altra domanda SO legati da post copre bene. atomico copre solo * l'accesso * alla proprietà - ad es. non si può riavere un int che è mezzo vecchio e mezzo nuovo, sarebbe tutto vecchio o nuovo di zecca (nel caso di obj-c fa anche una garanzia sui conti di mantenimento). In generale, possono essere necessarie serrature/barriere complete. Tuttavia, l'accesso atomico (non CAS, che è diverso) può essere utilizzato in alcuni algoritmi "lock-free" e/o loop di thread just-get-me-out. Quindi sì, coprono un po 'di terreno limitato. –

+0

possibile duplicato di [proprietà Objective-C: atomico vs nonatomico] (http://stackoverflow.com/questions/588866/objective-c-properties-atomic-vs-nonatomic) – bbum

+0

@pst Completamente corretto e alcuni tipi di scalari su alcune ABI che possono essere parziali. Penso che sia stato PPC a mettere metà di un particolare tipo scalare in un registro e l'altra metà allo stack in modo tale da poter effettivamente ottenere un comportamento di mezza-vecchia-mezza su uno scalare con valore singolo altrimenti! – bbum

risposta

6

Non ti manca nulla; L'utilità di atomic è in gran parte limitata alle situazioni in cui è necessario accedere o impostare un valore particolare da più thread dove tale valore è anch'esso integrale.

Oltre un valore singolo, atomic non può essere utilizzato per scopi di sicurezza thread.

Ho scritto un bel po 'su di esso in un weblog post a while ago.

questa domanda è anche un [molto ben posto] duplicato di What's the difference between the atomic and nonatomic attributes?

+0

Siamo spiacenti di riavviare una discussione 3 anni dopo ma @bbum, intendevi "dove il valore non è integrale" poiché l'atomicità non ti garantisce quale valore, solo un valore legittimo? Sto cercando di capire questa roba così semplicemente chiedendo il mio chiarimento. – MoMo

+0

@MoMo Right.L'atomicità garantisce semplicemente l'integrità del valore, non se otterrà il valore nuovo o vecchio. E anche la frase "oltre un singolo valore" è a volte errata. Su PPC, i valori a 64 bit potrebbero a volte essere suddivisi tra un registro a 32 bit e una voce di stack a 32 bit. – bbum

Problemi correlati