I know it's possible to solve reader-writer issues in GCD using barriers. Since I (generally) try to use NSOperationQueue
instead of GCD when performance isn't a key issue, I'd like an NSOperation
-compatible solution to this issue.
I've tried to write my own, but my solution has become unwieldy...surely someone has tackled this problem already?
Does anyone know of an NSOperation
-compatible solution to the reader-writer problem?
READERS WRITERS PROBLEM The readers-writers problem is a classical problem of process synchronization, it relates to a data set such as a file that is shared between more than one process at a time.
The readers-writers problem is used for managing synchronization among various reader and writer process so that there are no problems with the data sets, i.e. no inconsistency is generated. Let's understand with an example - If two or more than two readers want to access the file at the same point in time there will be no problem.
If for some reason the first reader doesn’t get the writer mutex, it’s stuck waiting while also holding onto the reader mutex. In other words, all readers are frozen until the first reader gets the writer mutex. Like semaphores, the monitors solution to concurrent reader access needs a few changes.
In Process-synchronization, there is a very classical synchronization problem named as Readers-writers problem. The problem has several sub-problems or variations all involving priorities, one of which is discussed in the above post. The second variation goes by the name Writer-priority readers-writers problem.
As with most NSOperationQueue
hackery, you can exploit its support for dependencies between operations:
NSBlockOperation
subclass, ReaderWriterBlockOperation
. Add to it property BOOL writer
.-readWithBlock:
and -writeWithBlock:
. Both enqueue an ReaderWriterBlockOperation
, the one with writer == NO
, the other == YES
. Their operation manages dependencies as follows:
-readWithBlock:
does, in an @synchronized(self)
block, a scan of the operations from last to first looking for a writer block. If none is found, it adds operation and returns. If one is found, it makes the new reader block dependent on the writer, enqueues it, and returns.-writeWithBlock:
does the same thing. Except if no writer is found in the queued operations, it makes the block dependent on all readers found. If one is found in the queued operations, it makes itself dependent on that operation and all following (reader) operations.This should have the result of blocking all readers till the writer before them has completed, and blocking all writers till the readers before them have completed.
One possible issue: I'm unclear (because the docs are unclear, and I haven't implemented this as such yet) if NSBlockOperation
actually waits for its block to finish running before declaring itself complete. If it doesn't, you'll need to manage that yourself in your operation subclass.
All that said, if the system provides a working solution, such as barrier blocks, you should use that. This whole system is a hack to get an operation queue to do something that dispatch queues have been tuned to handle very well. If performance is not in fact a concern, then why not just use a serial queue (NSOperationQueue
with max concurrent operation count == 1)?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With