如何通过调度并发队列(GCD)实现可重入锁定机制?

Sta*_*ich 5 objective-c grand-central-dispatch

我刚读过这篇文章,其解决方案似乎令人信服:

  • 串行队列用于同步访问
  • dispatch_get_specific/dispatch_set_specific用于提供重入功能.

我感兴趣的是,如果有可能推动这一方案来实现重入锁定机制并行调度队列(每次读取使用dispatch_sync做,写使用dispatch_barrier_async做,等进行了说明这里,看到"一个资源,多个读卡器,和一个单一的作家").

PS我想我已经设法在[NSThread currentThread].threadDictionary 这里实现了这个,但我不喜欢处理[NSThread currentThread]因为我依赖GCD.是否有可能[NSThread currentThread].threadDictionary用一些棘手的dispatch_set_specific/dispatch_get_specific代码替换使用?

ipm*_*mcc 9

如果我对此问题发表评论,你在评论链接帖子时问过我.对不起,我花了很长时间,但我记得第一次看到它时,我觉得我没有任何富有成效的说法.但是今天我被提醒了这个话题并回过头来看这个问题,并且想到我会拍摄一下:

总的来说,我建议不要走这条路.正如我在链接到/从答案中解释的那样,实现递归"锁定" 绝不dispatch_get/set_specific是防弹的,超越简单的串行案例到单作者/多读者语义不会消除这些问题,可能会引入更多问题.dispatch_barrier_[a]sync

顺便说[NSThread threadDictionary]一句,如果您只是寻找替代线程局部存储的方法,也许是以非Objective-C API的形式,那么您应该使用pthread_setspecificpthread_getspecific.这些是较低级别的POSIX调用[NSThread threadDictionary](几乎可以肯定)构建的.

退一步:在经验丰富的系统程序员中有一种非常强烈的感情,即递归锁是一种反复模式,应该避免.这是一篇关于这个主题有趣论文.(如果你对为什么在POSIX中存在递归互斥体的伪造故事不感兴趣,只需搜索"客观事实"跳转到与这个问题相关的部分.)那篇文章是用更原始的"锁定"来编写的.尽管在某些常见情况下队列可以(有时非常有用)适应模拟锁,但是(由互斥和条件组成)与队列根本不同.然而,即使它们不同,如​​果你考虑到Butenhof对递归原始锁的批评,很快就会发现,在许多递归锁是"坏"的方法中,使用队列来模拟锁更糟糕.例如,在最基本的级别,你可以解锁锁定模拟队列的唯一方法是返回; 有没有其他的方法来释放一个基于队列的锁.当调用者继续持有它时,调用可能需要以递归方式重新输入该锁的其他代码,是"锁定"被保持的时间的潜在无限延伸.

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

总而言之,尝试调整GCD的并发队列屏障行为以模拟递归读取器/写入器锁定感觉就像一个失败的命题.充其量,它总是受限于我在这里为串行情况解释的限制.在最坏的情况下,您将发布一种最终会降低并发性的模式.