2013-11-25 20 views
4

刚才我看到this post,它的解决方案似乎更让人信服:如何通过调度并发队列(GCD)实现可重入锁定机制?

  • 串行队列来同步访问
  • dispatch_get_specific/dispatch_set_specific用于提供再进入能力。

我感兴趣的是,如果有可能推动这一方案来实现折返锁定机制并发调度队列(每次读取使用dispatch_sync等进行了说明here, see "One Resource, Multiple Readers, and a Single Writer"做,写使用dispatch_barrier_async完成) 。

P.S.我想我已经设法实现这个使用[NSThread currentThread].threadDictionaryhere,但我不喜欢与[NSThread currentThread]打交道,因为我依靠GCD。是否有可能用一些棘手的dispatch_set_specific/dispatch_get_specific代码代替[NSThread currentThread].threadDictionary的用法?

+0

这篇文章有点陈旧,但是,有什么理由不能仅仅为你想要做的事情使用dispatch_get_specific?如果你创建了一个并发调度队列(而不是全局调度队列),难道你不会做同样的事情吗? – JPC

+0

@JPC,看起来你是对的。描述我的错误的时间太长(为什么我觉得这是一个不同的情况)...随意将这个评论的格式设置为答案,我会接受它是正确的。 –

+0

感谢您的顺便!我现在可以重新访问我的原始代码,并消除所有这些[NSThread currentThread]的东西。 –

回答

6

如果我对这个问题发表评论,你问我对链接帖子的评论。对不起,我花了这么长时间,但我记得第一次看着它,我不觉得我有什么生产力的话。但今天我被提醒了这个话题,并回过头来看这个问题,并认为我会拍摄:

总的来说,我建议不要走这条路。正如我在the linked-to/from answer中所解释的那样,执行dispatch_get/set_specific的递归“锁定”是从不防弹,并且超出简单的序列情况到dispatch_barrier_[a]sync的单写/多读者语义不会消除这些问题,并且可能会引入更多问题。另一方面,如果您只是寻找[NSThread threadDictionary]作为线程本地存储的备选方案(可能采用非Objective-C API的形式),那么您应该使用pthread_setspecificpthread_getspecific。这些是较低级别的POSIX调用,其中[NSThread threadDictionary](几乎可以肯定)建立。

退一步:退伍军人系统程序员中有一种非常强烈的情绪,认为递归锁是一种反向模式,应该避免。这是一个interesting treatise on the subject。 (如果你对POSIX中存在递归互斥体的原因不感兴趣,只需搜索“客观事实”即可跳到与这个问题相关的部分)。该部分是根据更原始的“锁“(由互斥体和条件组成),尽管队列可以(有时非常有用)适用于模拟某些常见情况下的锁,但它与队列根本不同。然而,即使它们不同,如​​果考虑Butenhof对递归原始锁的批评,很快就会发现,在许多递归锁“坏”的方式中,使用队列来模拟锁是更糟糕的。例如,在最基本的层次上,你可以解锁一个模拟队列的唯一方法是返回;有没有其他方式释放基于队列的锁。调用其他代码时,可能需要递归地重新输入该锁,而调用者继续保持它,这是“锁”持续时间的潜在无限延伸。

对我很好的一般建议是“使用最高级别的抽象来完成工作。“在这个问题的上下文中,这将转化为(暂时搁置前面对递归锁定的批评):如果您在Objective-C中工作,并且由于某种原因,您需要递归锁定,请使用@synchronized。当性能分析告诉你,你的@synchronized使用实际上是造成你一个问题,然后考虑更好的解决方案(有先见之明,知道“更好的解决方案”很可能需要移动从递归锁走在一起。)

总之,试图修改GCD的并发队列阻塞行为来模拟一个递归的读写器锁定感觉就像是一个失败的提议,最好的情况是它总是受限于我为系列案例解释over here。 '公布g最终降低并发性的模式。

+1

非常感谢您的回答,@ipmcc!我需要一些时间来阅读和理解你指出的所有事情。顺便说一下,你是SO上最好的作家之一。 –