Il est rare que NSLock
soit le bon outil pour ce travail. Il y a beaucoup de meilleurs outils maintenant, en particulier avec GCD; plus tard.
Comme vous le savez probablement déjà de the docs, mais je vais le répéter pour ceux qui lisent le long:
Avertissement: La classe NSLock utilise pour mettre en œuvre les threads POSIX son comportement de verrouillage. Lorsque vous envoyez un message de déverrouillage à un objet NSLock, vous devez vous assurer que ce message est envoyé par le même thread qui a envoyé le message de verrouillage initial. Déverrouiller un verrou à partir d'un thread différent peut entraîner un comportement indéfini.
C'est très difficile à implémenter sans interblocage si vous essayez de verrouiller et déverrouiller sur différents threads. Le problème fondamental est que si lock
bloque le thread, alors il n'y a aucun moyen pour que le unlock
suivant s'exécute sur ce thread, et vous ne pouvez pas unlock
sur un thread différent. NSLock
n'est pas pour ce problème. Au lieu de NSLock
, vous pouvez implémenter les mêmes modèles avec dispatch_semaphore_create()
. Ceux-ci peuvent être mis à jour en toute sécurité sur n'importe quel fil que vous aimez. Vous pouvez verrouiller en utilisant dispatch_semaphore_wait()
et vous pouvez déverrouiller en utilisant dispatch_semaphore_signal()
. Cela dit, ce toujours n'est généralement pas la bonne réponse.
La plupart des conflits de ressources sont mieux gérées avec une file d'attente d'opérations ou une file d'attente de répartition. Ceux-ci fournissent d'excellents moyens de gérer le travail en parallèle, de gérer les ressources, d'attendre les événements, d'implémenter des modèles de producteur/consommateur et de faire presque tout ce que vous auriez fait avec un NSLock
ou NSThread
auparavant. Je recommande fortement le Concurrency Programming Guide comme une introduction à la façon de concevoir avec des files d'attente plutôt que des verrous.