Rzadko zdarza się, że NSLock
jest właściwym narzędziem do pracy. Teraz jest o wiele lepsze narzędzie, szczególnie w przypadku GCD; więcej później.
Jak już zapewne wiesz z the docs, ale powtórzę dla tych, czytając razem:
Ostrzeżenie: klasa NSLock korzysta z POSIX wątki do wdrożenia jego zachowanie blokującą. Wysyłając wiadomość odblokowującą do obiektu NSLock, musisz mieć pewność, że wiadomość jest wysyłana z tego samego wątku, który wysłał początkową wiadomość blokującą. Odblokowanie blokady z innego wątku może spowodować niezdefiniowane zachowanie.
To bardzo trudne do wdrożenia bez zakleszczenia, jeśli próbujesz zablokować i odblokować na różnych wątkach. Podstawowym problemem jest to, że jeśli lock
blokuje wątek, to nie ma możliwości, aby kolejny unlock
kiedykolwiek uruchomił się na tym wątku, a Ty nie możesz unlock
na innym wątku. NSLock
nie dotyczy tego problemu.
Zamiast NSLock
można zastosować te same wzory z dispatch_semaphore_create()
. Można je bezpiecznie aktualizować w dowolnym wątku. Możesz zablokować za pomocą dispatch_semaphore_wait()
i możesz odblokować za pomocą dispatch_semaphore_signal()
. To powiedziawszy, ta nadal nie jest właściwą odpowiedzią.
Większość rywalizacji o zasoby najlepiej zarządzać za pomocą kolejki operacji lub kolejki wysyłkowej. Zapewniają one doskonałe sposoby równoległego obsługiwania pracy, zarządzania zasobami, czekania na zdarzenia, wdrażania wzorców producenta/konsumenta, a także wykonywania prawie wszystkiego, co wcześniej byś zrobił z NSLock
lub NSThread
. Bardzo polecam Concurrency Programming Guide jako wprowadzenie do tego, jak projektować za pomocą kolejek, a nie blokad.