objective-c - temporizzato - threads in java




Qual è il thread-safe atomico o non atomico? (5)

Ho cercato e trovato immutabile sono thread sicuro mentre mutabile non lo è. Questo va bene. Ma ho delle note fuorvianti, dei blog, delle risposte atomiche e non atomiche sulla sicurezza dei thread, gentilmente do una spiegazione per la risposta.

Supponiamo che ci sia una proprietà di stringa atomica chiamata "nome", e se chiami [self setName:@"A"] dal thread A, chiama [self setName:@"B"] dal thread B e chiama [self name] da thread C, quindi tutte le operazioni su thread diversi verranno eseguite in serie, il che significa che se un thread sta eseguendo setter o getter, allora altri thread attenderanno. Questo rende la proprietà "nome" in lettura / scrittura sicura, ma se un altro thread D chiama [name release] contemporaneamente, questa operazione potrebbe causare un arresto anomalo perché non è presente alcuna chiamata setter / getter. Il che significa che un oggetto è in lettura / scrittura sicuro (ATOMIC) ma non thread safe poiché un altro thread può inviare contemporaneamente qualsiasi tipo di messaggio all'oggetto.

Se il "nome" della proprietà era nonatomico, tutti i thread nell'esempio precedente - A, B, C e D verranno eseguiti simultaneamente producendo risultati imprevedibili. In caso di atomico, uno di A, B o C verrà eseguito per primo ma D può ancora essere eseguito in parallelo.

Il tuo commento su questo ci aiuterà ....

E la mia domanda è "che è sicuro per il thread nel cacao, atomico o non atomico?"



C'è un'altra proprietà di "atomico" che non è stata menzionata, che era necessaria per la sicurezza dei thread prima di ARC (e probabilmente lo è ancora). Prima spieghiamo perché è necessario: Diciamo che senza ARC, si legge una proprietà dell'oggetto e la si conserva immediatamente. Ma un altro thread potrebbe entrare solo tra voi che leggete la proprietà e la chiamata di conservazione, impostate la proprietà dell'oggetto su zero, facendo sì che l'oggetto venisse deallocato. Si invia il retain a un oggetto deallocato, che non è sano. E sarebbe un errore molto raro, perché succede solo quando i tempi sono giusti. Per evitare ciò, le proprietà degli oggetti atomici restituiscono sempre oggetti autoreleased.


Non atomico è thread-safe. Guranted ottiene il valore della variabile.


Per ObjC Properties - Né sono thread safe .

Atomic è più resistente agli errori di threading. Nel complesso, è un insolito insolito. Gli scenari che preferiresti agli atomici sono pochissimi. Atomico può aumentare la probabilità di correttezza, ma è troppo basso per essere considerato un sostituto per un meccanismo di bloccaggio adeguato. Pertanto, se hai bisogno di sicurezza del thread, hai ancora bisogno di qualche altra primitiva di sincronizzazione sopra le letture / scritture atomiche. Se non si ha bisogno della sicurezza del thread (ad esempio l'istanza è immutabile o destinata all'esecuzione solo dal thread principale), atomic non aggiungerà nulla.

Essere resistenti agli errori di threading non è una "qualità", serve a mascherare gli errori reali di threading e renderli più difficili da riprodurre e rilevare.

Si noti inoltre che i tipi mutabili e immutabili non garantiscono effettivamente la sicurezza del thread. 'Mutabile' può essere usato nei nomi ObjC per riferirsi solo all'interfaccia - le parti interne di un'istanza immutabile possono effettivamente avere uno stato interno mutabile. In breve, non si può presumere che un tipo che ha una sottoclasse mutabile sia sicuro per i thread.

Domanda estesa:

Supponiamo che ci sia una proprietà di stringa atomica chiamata "nome", e se chiami [self setName: @ "A"] dal thread A, chiama [self setName: @ "B"] dal thread B e chiama [self name] da thread C, quindi tutte le operazioni su thread diversi verranno eseguite in serie, il che significa che se un thread sta eseguendo setter o getter, allora altri thread attenderanno.

Se tutti i thread cercassero di leggere e / o scrivere sulla proprietà contemporaneamente, solo un thread avrebbe accesso alla volta e gli altri sarebbero bloccati se la proprietà fosse atomica. Se la proprietà fosse non anatomica, allora tutti avrebbero accesso non controllato alla lettura e alla scrittura della variabile allo stesso "tempo".

se un altro thread D chiama [nome release] contemporaneamente, questa operazione potrebbe causare un arresto anomalo perché non è presente alcuna chiamata setter / getter.

Corretta.

Il che significa che un oggetto è in lettura / scrittura sicuro (ATOMIC) ma non thread safe poiché un altro thread può inviare contemporaneamente qualsiasi tipo di messaggio all'oggetto.

Bene, c'è davvero molto di più. L'esempio comune è:

    @interface MONPerson : NSObject

    @property (copy) NSString * firstName;
    @property (copy) NSString * lastName;

    - (NSString *)fullName;

    @end

Atomico o nonatomico, è necessario un meccanismo di sincronizzazione (ad es. Blocco) se un thread sta leggendo da quell'istanza e un altro sta scrivendo su di esso. Potresti finire con il firstName di un MONPerson e il cognome di un altro - L'oggetto potrebbe essere cambiato prima che il valore di ritorno del getter sia restituito anche a te, o questo può accadere:

Discussione A:

p.firstName = @"Rob";

Discussione B:

p.firstName = @"Robert";

Discussione A:

label.string = p.firstName; // << uh, oh -- will be Robert

Se il "nome" della proprietà era nonatomico, tutti i thread nell'esempio precedente - A, B, C e D verranno eseguiti simultaneamente producendo risultati imprevedibili.

Giusto: i sintomi iniziali possono essere squilibri di conteggio di riferimento (perdita, sovra-rilascio).

In caso di atomico, uno di A, B o C verrà eseguito per primo ma D può ancora essere eseguito in parallelo. Si prega di commentare questo ....

Corretta. Ma se si guarda all'esempio di cui sopra - solo atomico è raramente un sostituto adatto per una serratura. Dovrebbe apparire come questo, invece:

Discussione A:

[p lock]; // << wait for it… … … …
// Thread B now cannot access p
p.firstName = @"Rob";
NSString fullName = p.fullName;
[p unlock];
// Thread B can now access p
label.string = fullName;

Discussione B:

[p lock]; // << wait for it… … … …
// Thread A now cannot access p
…
[p unlock];

Gli accessori atomici possono avere una media di oltre venti volte più lentamente degli accessi non anatomici. Inoltre, se la classe ha bisogno di essere protetta da thread e ha uno stato mutabile, è probabile che si utilizzi un blocco quando opera in uno scenario concorrente. Il blocco corretto fornisce tutte le garanzie di cui hai bisogno: gli accessor atomici sono ridondanti in tale scenario, l'uso di atomics aggiungerebbe solo il tempo della CPU. Un altro aspetto positivo del blocco regolare è che hai tutta la granularità di cui hai bisogno - anche se è spesso più pesante dello spin lock usato per gli atomici, in genere avrai bisogno di meno acquisizioni quindi sarà molto veloce se usi correttamente i blocchi regolari .


atomic rende sicuro il seguente thread.

self.myProperty = value;

o

id value = self.myProperty

non rende sicuro il seguente thread

[myPorperty addObject:value];

Atomic lo rende thread sicuro per impostare o ottenere una proprietà, ma non rende sicuro threading dei metodi di quella proprietà stessa.

l'impostazione o il recupero dei valori può richiedere più di un'istruzione CPU e ciò significa che l'impostazione o il recupero possono essere interrotti a metà e un altro thread può fare qualcosa che rende l'avanzamento del thread precedente nell'impostazione o che il valore non è valido.

atomic dice set o ottiene il valore in modo che accada come se fosse accaduto con un'istruzione indivisibile e quindi nessun altro thread può intervenire a metà e rovinare tutto.

Gli oggetti immutabili sono thread-safe semplici perché non puoi cambiarli, perché puoi cambiare una proprietà da un oggetto immutabile un altro in modo tale che la parte non sia sicura fino a quando non la fai atomica.





atomic