Как заблокировать NSLock в определенном потоке
У меня есть собственность @property NSLock *myLock
И я хочу написать два метода:
- (void) lock
а также
- (void) unlock
Эти методы блокируют и разблокируют myLock
соответственно, и они должны делать это независимо от того, какой поток или очередь их вызвали. Например, поток А мог бы вызвать lock
но очередь B может быть тем, кто вызывает unlock
, Оба эти метода должны работать надлежащим образом, не сообщая о том, что я пытаюсь разблокировать блокировку из другого потока / очереди, которая ее заблокировала. Кроме того, они должны делать это синхронно.
1 ответ
Редко что NSLock
это правильный инструмент для работы. Сейчас есть намного лучшие инструменты, особенно с GCD; позже.
Как вы, вероятно, уже знаете из документов, но я повторю для тех, кто читает вместе:
Предупреждение: класс NSLock использует потоки POSIX для реализации своего поведения блокировки. При отправке сообщения разблокировки объекту NSLock вы должны быть уверены, что сообщение отправлено из того же потока, который отправил сообщение начальной блокировки. Разблокировка блокировки из другого потока может привести к неопределенному поведению.
Это очень трудно реализовать без взаимоблокировки, если вы пытаетесь заблокировать и разблокировать разные потоки. Основная проблема заключается в том, что если lock
блокирует поток, тогда нет возможности для последующего unlock
когда-либо работать в этой теме, и вы не можете unlock
в другой теме. NSLock
не для этой проблемы.
Скорее, чем NSLock
Вы можете реализовать те же шаблоны с dispatch_semaphore_create()
, Они могут быть безопасно обновлены в любой теме, которая вам нравится. Вы можете заблокировать с помощью dispatch_semaphore_wait()
и вы можете разблокировать с помощью dispatch_semaphore_signal()
, Тем не менее, это все еще обычно не правильный ответ.
Большая часть конфликтов ресурсов лучше всего управляется с помощью очереди операций или очереди отправки. Они предоставляют отличные способы для параллельной работы, управления ресурсами, ожидания событий, реализации шаблонов "производитель / потребитель", а в остальном делают почти все, что вы сделали бы с NSLock
или же NSThread
в прошлом. Я настоятельно рекомендую Руководство по программированию параллелизма как введение в проектирование с использованием очередей, а не блокировок.