6

我有财产@property NSLock *myLock

我想写两种方法:

- (void) lock

- (void) unlock

myLock这些方法分别锁定和解锁无论是什么线程或队列调用它们,它们都需要执行此操作。例如,线程 A 可能已经调用lock,但队列 B 可能是调用的那个unlock。这两种方法都应该正常工作,而不会报告我正在尝试从锁定它的不同线程/队列中解锁锁。此外,他们需要同步执行此操作。

4

1 回答 1

27

NSLock适合这项工作的工具已经很少见了。现在有更好的工具,尤其是 GCD;以后再说。

正如您可能已经从文档中知道的那样,但我会为那些阅读的人重复一遍:

警告: NSLock 类使用 POSIX 线程来实现其锁定行为。向 NSLock 对象发送解锁消息时,您必须确保该消息是从发送初始锁定消息的同一线程发送的。从不同的线程解锁锁可能会导致未定义的行为。

如果您尝试在不同的线程上锁定和解锁,那么在没有死锁的情况下很难实现。根本问题是,如果lock阻塞线程,那么后续线程就无法在unlock该线程上运行,并且您不能unlock在不同的线程上运行。NSLock不是为了这个问题。

而不是NSLock,您可以使用 实现相同的模式dispatch_semaphore_create()。这些可以在您喜欢的任何线程上安全地更新。您可以使用 锁定dispatch_semaphore_wait(),也可以使用 解锁dispatch_semaphore_signal()。也就是说,这通常仍然不是正确的答案。

大多数资源争用最好通过操作队列或调度队列来管理。这些提供了很好的方法来并行处理工作、管理资源、等待事件、实现生产者/消费者模式,以及做几乎所有你过去会做的NSLock事情NSThread。我强烈推荐并发编程指南作为如何使用队列而不是锁进行设计的介绍。

于 2013-04-11T15:24:37.743 回答