5

Ho un immobile @property NSLock *myLockCome bloccare un NSLock su uno specifico thread

E voglio scrivere due metodi:

- (void) lock 

e

- (void) unlock 

Questi metodi bloccare e sbloccare myLock rispettivamente e hanno bisogno di farlo indipendentemente da quale thread o coda li ha chiamati. Ad esempio, il thread A potrebbe aver chiamato lock ma la coda B potrebbe essere quella che chiama unlock. Entrambi questi metodi dovrebbero funzionare in modo appropriato senza segnalare che sto cercando di sbloccare un blocco da un thread/coda diverso che lo ha bloccato. Inoltre, hanno bisogno di farlo in modo sincrono.

risposta

23

È raro che NSLock sia lo strumento giusto per il lavoro. Ci sono strumenti molto migliori ora, in particolare con GCD; più tardi.

Come probabilmente già sapete da the docs, ma lo ripeto per chi legge insieme:

Attenzione: La classe NSLock utilizza i thread POSIX per attuare il suo comportamento di chiusura. Quando si invia un messaggio di sblocco a un oggetto NSLock, è necessario assicurarsi che il messaggio venga inviato dallo stesso thread che ha inviato il messaggio di blocco iniziale. Sbloccare un lucchetto da una filettatura diversa può comportare un comportamento indefinito.

Questo è molto difficile da implementare senza deadlock se si sta cercando di bloccare e sbloccare su thread diversi. Il problema fondamentale è che se lock blocca il thread, non è possibile che il successivo unlock venga eseguito su quel thread e che non sia possibile eseguire unlock su un thread diverso. NSLock non è per questo problema.

Anziché NSLock, è possibile implementare gli stessi motivi con dispatch_semaphore_create(). Questi possono essere tranquillamente aggiornati su qualsiasi thread che ti piace. Puoi bloccare utilizzando dispatch_semaphore_wait() e puoi sbloccarlo utilizzando dispatch_semaphore_signal(). Detto questo, questo è ancora il di solito non è la risposta giusta.

La maggior parte del conflitto di risorse viene gestita al meglio con una coda di operazioni o una coda di invio. Questi forniscono eccellenti modi per gestire il lavoro in parallelo, gestire le risorse, attendere gli eventi, implementare modelli produttore/consumatore, e in caso contrario fare quasi tutto ciò che avresti fatto con uno NSLock o NSThread in passato. Consiglio vivamente lo Concurrency Programming Guide come introduzione a come progettare con le code anziché i blocchi.

Problemi correlati