可重入读/写锁定构造?

时间:2012-10-07 02:29:17

标签: objective-c ios multithreading locking

我是一名经验丰富的.NET程序员,并且在iOS上伸展双腿。 .NET中我最喜欢的多线程构造之一是ReaderWriterLock。它允许多个读者或单个作者。我在iOS中真正缺少的一个功能是锁是可重入的。也就是说,reader threads can acquire the read lock multiple times只要它们释放相同的次数即可。同样,只要单个写入器线程以相同的数量释放锁定,它就可以多次获取锁定。

我已经研究过iOS框架,并且没有一个构造似乎提供相同的支持,包括重新入侵。我也查看了pthread库。我找到了rwlock,但它不允许重入。

iOS上是否有允许重入读写锁的内容?

2 个答案:

答案 0 :(得分:17)

是的,@synchronized指令是可重入的。请参阅“线程编程指南”中的Using the @synchronized Directive以及ObjC编程语言中的Threading

那就是说,你几乎不应该在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;
});

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

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

答案 1 :(得分:2)

来自iOS Threading Programming Guide

  

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

所以我猜如果pthreads不支持re-entrancy,答案是否定的。