Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read-Write lock with GCD

My application makes heavy use of GCD, and almost everything is split up in small tasks handled by dispatches. However, the underlying data model is mostly read and only occasionally written.

I currently use locks to prevent changes to the critical data structures while reading. But after looking into locks some more today, I found NSConditionLock and some page about read-write locks. The latter is exactly what I need.

I found this implementation: http://cocoaheads.byu.edu/wiki/locks . My question is, will this implementation work with GCD, seeing that it uses PThreads?

like image 407
Erik S Avatar asked Apr 19 '12 18:04

Erik S


2 Answers

It will still work. pthreads is the threading API which underlies all of the other thread-using APIs on Mac OS X. (Under that there's Mach thread activations, but that's SPI, not API.) Anyway, the pthreads locks don't really require that you use pthreads threads.

However, GCD offers a better alternative as of iOS 5: dispatch_barrier_async(). Basically, you have a private concurrent queue. You submit all read operations to it in the normal fashion. You submit write operations to it using the barrier routines. Ta-da! Read-write locking.

You can learn more about this if you have access to the WWDC 2011 session video for Session 210 - Mastering Grand Central Dispatch.

like image 196
Ken Thomases Avatar answered Sep 19 '22 17:09

Ken Thomases


You might also want to consider maintaining a serial queue for all read/write operations. You can then dispatch_sync() writes to that queue to ensure that changes to the data model are applied promptly and dispatch_async() all the reads to make sure you maintain nice performance in the app.

Since you have a single serial queue on which all the reads and writes take place you ensure that no reads can happen during a write. This is far less costly than a lock but it means you cannot execute multiple 'read' operations simultaneously. This is unlikely to cause a problem for most applications.

Using dispatch_barrier_async() might mean that writes you make take an arbitrary amount of time to actually be committed since all the pre-existing tasks in the queue have to be completed before your barrier block executes.

like image 43
mjmdavis Avatar answered Sep 17 '22 17:09

mjmdavis