我的应用程序大量使用GCD,并且几乎所有东西都被分派到由调度处理的小任务中。但是,底层数据模型大部分是读取的,只是偶尔写入。用GCD读写锁定
我目前使用锁来防止在读取时更改关键数据结构。但今天看了更多锁之后,我发现了NSConditionLock和一些关于读写锁的页面。后者正是我所需要的。
我发现这个实现:http://cocoaheads.byu.edu/wiki/locks。我的问题是,这个实现与GCD一起工作,看到它使用PThreads?
我的应用程序大量使用GCD,并且几乎所有东西都被分派到由调度处理的小任务中。但是,底层数据模型大部分是读取的,只是偶尔写入。用GCD读写锁定
我目前使用锁来防止在读取时更改关键数据结构。但今天看了更多锁之后,我发现了NSConditionLock和一些关于读写锁的页面。后者正是我所需要的。
我发现这个实现:http://cocoaheads.byu.edu/wiki/locks。我的问题是,这个实现与GCD一起工作,看到它使用PThreads?
它仍然有效。 pthreads是线程API,它是Mac OS X上所有其他线程使用API的基础。(在那之下有Mach线程激活,但这是SPI,而不是API)。无论如何,pthreads锁并不真的需要你使用pthreads线程。
但是,GCD为iOS 5提供了一个更好的选择:dispatch_barrier_async()
。基本上,你有一个私人的并发队列。您以正常方式将所有读取操作提交给它。您使用屏障例程向其提交写入操作。当当!读写锁定。
如果您有权访问WWDC 2011 session video for Session 210 - Mastering Grand Central Dispatch,则可以了解更多信息。
您可能还想考虑为所有读/写操作维护一个串行队列。然后,您可以向该队列写入数据,以确保对数据模型的更改立即应用,并确保您在应用中保持良好的性能。
既然你有一个单一的串行队列,所有的读写操作都发生,你确保在写入过程中不会发生读操作。这比锁的成本低得多,但这意味着你不能同时执行多个“读取”操作。这不太可能对大多数应用程序造成问题。
使用dispatch_barrier_async()
可能意味着您编写的文件需要耗费大量的时间才能真正提交,因为队列中的所有预先存在的任务必须在您的barrier块执行之前完成。
嗯,我甚至没有意识到串行队列上的异步调度是可能的。这听起来像一个有趣的想法......所有读取都是相当小的编辑,但写入通常意味着读取,编辑并再次保存数据。 – 2012-05-06 09:17:26
通常情况下,你会做与本文建议的相反的内容。读取通常必须同步提交,因为在返回给调用者之前,您通常需要获得结果。写操作可以异步完成,因为调用者只关心来自外部的状态可观察值与已写入的日期是否一致,这是因为在队列是串行的写入完成之前不能进行读操作。如上所述,这对多个读者没有帮助。 – 2012-05-12 03:01:39
啊,我已经读过关于屏障的信息,但当时想不出一个实际的应用程序(当时我几乎没有使用多线程)并忘记了所有关于它们的内容。谢谢,我会试着看看我能否使用它! – 2012-04-19 19:09:51
Mike Ash还提供了一个很好的例子,说明如何使用GCD完成读写器同步。 http://www.mikeash.com/pyblog/friday-qa-2011-10-14-whats-new-in-gcd.html – 2013-04-03 07:15:03