5

我有一个属性@property NSLock *myLock如何锁定NSLock在一个特定的线程

我想写两个方法:

- (void) lock 

- (void) unlock 

这些方法锁定和解锁myLock分别是他们需要这样做,而不管它们是什么线程或队列。例如,线程A可能调用了lock,但队列B可能是调用unlock的那个。这两种方法都应该适当地工作,而不报告我正试图解锁来自锁定它的不同线程/队列的锁。另外,他们需要同步做到这一点。

回答

23

NSLock这个工作非常罕见。现在有更好的工具,特别是GCD;更晚。

正如你可能已经从the docs知道,但我会重复那些一起阅读:

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

如果您尝试在不同的线程上锁定和解锁,那么如果没有死锁就很难实现。根本的问题是,如果lock阻塞该线程,则后续的unlock无法在该线程上运行,并且不能在另一个线程上运行unlockNSLock不适用于此问题。

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

大多数资源争用最好使用操作队列或分派队列进行管理。这些提供了并行处理工作,管理资源,等待事件,实施生产者/消费者模式,以及其他几乎所有您在过去使用NSLockNSThread所做的所有事情的绝佳方式。我强烈推荐Concurrency Programming Guide作为介绍如何设计队列而不是锁定。