16

我是一位经验丰富的 .NET 程序员,并且正在使用 iOS 伸展我的腿。.NET 中我最喜欢的多线程结构之一是ReaderWriterLock。它允许多个读取器或单个写入器。我在 iOS 中真正缺少的一个功能是锁是可重入的。也就是说,读取器线程可以多次获取读取锁,只要它们释放它的次数相同。同样,单个写入线程可以多次获取锁,只要它释放相同数量的锁即可。

我研究了 iOS 框架,似乎没有一个结构提供相同的支持,包括重入。我还查看了 pthread 库。我找到了rwlock,但它不允许重入。

iOS上有什么允许重入读写锁的吗?

4

2 回答 2

19

是的,该@synchronized指令是可重入的。请参阅线程编程指南中的使用 @synchronized指令以及ObjC 编程语言中的线程。

也就是说,你几乎不应该在 iOS 中使用它。在大多数情况下,您可以避免使用各种锁,更不用说重入锁之类的重量级(慢速)锁了。请参阅并发编程指南,特别是Migrating Away from Threads部分,了解 iOS 偏爱的基于队列的方法而不是手动线程管理和锁定的详细信息。

例如,读/写锁使用 Grand Central Dispatch 的工作方式如下:

- (id)init {
   ...
   _someObjectQueue = dispatch_queue_create("com.myapp.someObject", 
                                            DISPATCH_QUEUE_CONCURRENT);
 }

// In iOS 5 you need to release disptach_release(_someObjectQueue) in dealloc,
// but not in iOS 6.

- (id)someObject {
  __block id result;
  dispatch_sync(self.someObjectQueue, ^{
    result = _someObject;
  });
  return result;
}

- (void)setSomeObject:(id)newValue {
  dispatch_barrier_async(self.queue, ^{
    _someObject = newValue;
});

这种方法允许使用独占写入器的无限并行读取器,同时确保写入器永远不会饿死,并且写入和读取是序列化的,同时避免任何内核调用,除非存在实际争用。这就是说它非常快速和简单。

当读者出现时,您将请求排队以读取该值,并等待它处理。当写入器出现时,它会将屏障请求排队以对其进行更新,这要求当前没有来自该队列的其他请求正在运行。使用这种结构,开发人员不需要管理任何锁。只需按照您希望它们运行的​​顺序将它们放入队列中。

于 2012-10-07T19:58:00.287 回答
2

来自 iOS线程编程指南

系统仅支持使用 POSIX 线程的读写锁。有关如何使用这些锁的更多信息,请参见pthread手册页。

所以我猜如果pthreads不支持重入,答案是否定的。

于 2012-10-07T03:45:47.950 回答