Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Solve reader-writer issues with NSOperationQueue?

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?

like image 286
Greg Maletic Avatar asked May 09 '14 00:05

Greg Maletic


People also ask

What is readers and writers problem in operating system?

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.

What is the purpose of the readers-writers problem?

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.

What happens if the first reader doesn’t get the writer mutex?

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.

What is the readers-writers problem in process synchronization?

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.


1 Answers

As with most NSOperationQueue hackery, you can exploit its support for dependencies between operations:

  • Create an NSBlockOperation subclass, ReaderWriterBlockOperation. Add to it property BOOL writer.
  • Create an operation queue per protected resource.
  • Stop exposing your operation queue to clients. Instead expose the API -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)?

like image 148
Jeremy W. Sherman Avatar answered Nov 13 '22 19:11

Jeremy W. Sherman