2010-12-28 19 views

risposta

21

@ risposta di d11wtq è corretto solo quando si scrive il proprio codice o progettare il proprio API.

È completamente errato quando si lavora con un set di API e si sbaglia in modo specifico quando si lavora con Core Data.

Nel contesto del funzionamento con Mac OS X e iOS, la sicurezza dei thread deve sempre essere considerata nel contesto del funzionamento con le API di sistema. Anche usando, per esempio, un NSArray significa che stai lavorando con le API di sistema.

O in generale, cosa significa "non il thread sicuro"?

Un'API non thread-safe è un'API in cui non è possibile interagire con l'API da più thread contemporaneamente. Potrebbero esserci anche ulteriori restrizioni che più spesso riguardano il thread principale. Ad esempio, quasi tutte le operazioni di disegno devono essere eseguite sul thread principale sia su Mac OS X che su iOS.

La documentazione Apple presuppone la sicurezza del thread è il caso eccezionale. Vale a dire, un'API è protetta da thread solo se la documentazione richiede esplicitamente la sicurezza del thread. Se non si fa menzione della sicurezza del thread, è necessario presumere che l'API non sia thread-safe.

In Obj-C, cosa significa in semplici termini ; "CoreData non è thread-safe"

Questa affermazione non è del tutto corretta, ma è un'assunzione sicura.

Nel caso di Core Data, il comportamento di interazione del thread è extremely well documented.

In breve, parti dell'API sono thread-safe (il coordinatore del negozio, ad esempio) e le parti sono esplicitamente non thread-safe. Mentre il MOC fornisce i metodi di blocco e sblocco, è possibile utilizzare anche con il blocco esterno. Ma non farlo. Sarà meno efficiente e più fragile; significativamente così. In generale, non utilizzare il blocco interno. CoreData è ottimizzato per avere un contesto per thread/coda.

(Risposta fisso basato sul feedback di TC. Grazie.)

+1

NSArray non dice esplicitamente che è thread safe almeno no nella documentazione della classe su http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html eppure è piuttosto comune utilizzare un NSMutableArray con un NSLock per proteggere l'accesso ad esso da più thread. Questo è quindi un uso non "sicuro"? – Dad

+0

NSArray è un caso limite; * tecnicamente * nessuna quantità di blocco lo renderà sicuro. * Realisticamente * l'implementazione è isolata fino al punto in cui l'incapsulamento del blocco è "abbastanza sicuro". Il problema, tuttavia, è che devi assicurarti che ** ogni singola chiamata al metodo ** su quell'array sia dietro i tuoi lucchetti; non puoi lasciare che l'array sfugga nel codice del framework, per esempio. – bbum

+0

È interessante notare che la parola "thread" non viene visualizzata nella "Guida alla programmazione delle raccolte" (http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Collections/Collections.html%23// apple_ref/doc/uid/10000034i) e "sicuro" appare solo una volta e parla dell'enumerazione e modifica della raccolta durante l'enumerazione (non sicura). – Dad

3

AGGIORNAMENTO | Si prega di vedere la risposta di @Bbum. Accetto che la mia risposta sia viziata e che @bbum sia corretta.

Se qualcosa viene descritto come "non thread-safe", significa che non sono state prese precauzioni speciali per garantire che non si arresti in modo anomalo se due thread separati tentano di utilizzarlo contemporaneamente. In generale, il codice che deve essere utilizzato da più di un thread richiede blocchi espliciti (o blocchi @synchronize) che avvolgono aspetti del codice. In particolare, qualsiasi oggetto/variabile che verrà modificato causerebbe quasi certamente un arresto anomalo se due thread vi scrivessero nello stesso momento (dato che scriverebbero sullo stesso indirizzo di memoria). Allo stesso modo, se un thread stava leggendo una variabile mentre un altro stava scrivendo su di esso, la garbage sarebbe stata restituita e il programma probabilmente si sarebbe bloccato.

L'utilizzo di @synchronized o NSLock o un mutex POSIX ecc. Garantisce che solo un thread possa eseguire un determinato blocco di codice in qualsiasi momento. Gli altri thread vengono bloccati e devono attendere fino al rilascio del blocco. C'è un leggero calo di prestazioni con l'uso di lock (e ovviamente alcuni overhead di sviluppo devono pensarci), così spesso il codice dichiara espressamente che non è thread-safe, lasciando te, l'utente che adotta il codice, per posizionare i blocchi come necessario (o limitare l'esecuzione di non thread-safe a un singolo thread).

Vedere la documentazione Apple per ulteriori informazioni sulla filettatura e filo di sicurezza:

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocThreading.html#//apple_ref/doc/uid/TP30001163-CH19-BCIIGGHG

+4

* Utilizzando @synchronized, o NSLock o un POSIX mutex ecc, assicura che solo un thread può eseguire un particolare blocco di codice in un dato momento. * In il contesto della domanda è ** completamente sbagliato **. Non è possibile utilizzare alcuna quantità di blocco per garantire che un'API thread non sicura sia resa sicura da thread! – bbum

+1

Il problema, più nello specifico, è che nessuno di questi garantisce che il blocco * that * venga eseguito solo su un thread alla volta. Non garantisce nulla su qualsiasi * blocco * altro che possa utilizzare anche l'API non sicura. Se due parti diverse del tuo programma - o del tuo programma e dell'implementazione di un'altra API che utilizzi - entrambe accedono all'API non sicura, accadono cose brutte indipendentemente dal numero di serrature inserite. –

+0

Grazie ragazzi, ho sicuramente imparato qualcosa qui. @hmthur dovrebbe accettare la risposta di @ bbum invece. – d11wtq

Problemi correlati