如何在特定线程上锁定NSLock

时间:2013-04-11 15:00:03

标签: ios objective-c multithreading grand-central-dispatch nslock

我有一个属性@property NSLock *myLock

我想写两种方法:

- (void) lock

- (void) unlock

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

1 个答案:

答案 0 :(得分:24)

很少见NSLock是适合这项工作的工具。现在有更好的工具,尤其是GCD;更晚些。

正如您可能已经从the docs了解到的那样,但我会重复阅读:

  

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

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

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

大多数资源争用最好使用操作队列或调度队列进行管理。这些方法提供了并行处理工作,管理资源,等待事件,实现生产者/消费者模式以及以前用NSLockNSThread完成的几乎所有操作的出色方法。我强烈建议Concurrency Programming Guide介绍如何使用队列而不是锁来设计。