【问题标题】:Read-Write lock with GCD带 GCD 的读写锁
【发布时间】:2013-01-27 03:50:40
【问题描述】:

我的应用程序大量使用 GCD,几乎所有内容都被拆分为由调度处理的小任务。但是,底层数据模型主要是读取的,只是偶尔写入。

我目前使用锁来防止在读取时更改关键数据结构。但是今天在查看了更多锁之后,我发现了 NSConditionLock 和一些关于读写锁的页面。后者正是我所需要的。

我找到了这个实现:http://cocoaheads.byu.edu/wiki/locks。我的问题是,这个实现是否可以与 GCD 一起使用,因为它使用 PThreads?

【问题讨论】:

    标签: iphone objective-c multithreading locking grand-central-dispatch


    【解决方案1】:

    它仍然可以工作。 pthreads 是线程 API,它是 Mac OS X 上所有其他线程使用 API 的基础。(在此之下有 Mach 线程激活,但那是 SPI,而不是 API。)无论如何,pthreads 锁并不真正要求您使用 pthreads线程。

    然而,从 iOS 5 开始,GCD 提供了更好的替代方案:dispatch_barrier_async()。基本上,您有一个私有并发队列。您以正常方式向它提交所有读取操作。您使用屏障例程向它提交写操作。达达!读写锁定。

    如果您可以访问WWDC 2011 session video for Session 210 - Mastering Grand Central Dispatch,您可以了解更多信息。

    【讨论】:

    • 啊,我读过障碍,但当时想不出一个实际的应用程序(我当时几乎没有使用多线程)并且忘记了它们。谢谢,我试试看能不能用!
    • Mike Ash 还提供了一个很好的例子,说明如何使用 GCD 完成读写器同步。 mikeash.com/pyblog/friday-qa-2011-10-14-whats-new-in-gcd.html
    【解决方案2】:

    您可能还需要考虑为所有读/写操作维护一个串行队列。然后您可以dispatch_sync() 写入该队列以确保及时应用对数据模型的更改,并dispatch_async() 进行所有读取以确保您在应用程序中保持良好的性能。

    由于您有一个串行队列,所有读取和写入都发生在该队列上,因此您可以确保在写入期间不会发生读取。这比锁的成本要低得多,但这意味着您不能同时执行多个“读取”操作。这不太可能对大多数应用程序造成问题。

    使用dispatch_barrier_async() 可能意味着您进行的写入需要任意时间才能实际提交,因为队列中的所有预先存在的任务都必须在您的屏障块执行之前完成。

    【讨论】:

    • 嗯,我什至没有意识到可以在串行队列上进行异步调度。这听起来是个有趣的想法……所有读取都是相当小的编辑,尽管写入通常意味着读取、编辑然后再次保存数据。
    • 通常,您的操作与此处建议的相反。读取通常必须同步提交,因为您通常需要在返回给调用者之前获得结果。写入可以异步完成,因为调用者只关心从外部观察到的状态是否与写入日期一致,这是因为在写入完成之前无法进行读取,因为队列是串行的。如前所述,对多个阅读器没有帮助。
    • 另外 dispatch_barrier_async() 将/可能最终死锁,像这样:stackoverflow.com/questions/36634315/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-25
    • 2011-12-04
    • 2012-11-08
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    相关资源
    最近更新 更多