Exercise 3: Working with the reader_writer_lock (Background)

Figure 1

In the previous exercise we showed you the motivation behind using the concurrency runtime’s synchronization primitives. You learned how the critical_section could be used to synchronize shared date between threads.

If you are ever faced with a scenario where you have multiple readers and very few writers, then using a critical_section when readers read the variable might not be the best idea. The Concurrency Runtime introduces a new class called the reader_writer_lock that can be of great help when working with such scenarios.

The reader_writer_lock

This class enables multiple threads to read from a shared resource at the same time but only allows one thread to write to it at a time. They share many characteristics with concurrency runtime’s critical section, reader writer locks are non-reentrant and block cooperatively. The reader writer lock resembles the Win32 Slim reader/writer locks (SRWLock). The reader_writer_lock performs better than critical section in read-mostly environments.

Similarity to Win32 Slim reader/writer locks

  • Can be used only by threads of a single process.
  • The reader writer lock can be owned by multiple reader-threads or only one writer thread at any time.
  • Non-reentrant.
  • Do not support upgrades or downgrades.

Differences with Win32 Slim reader/writer locks:

  • The concurrency runtime’s reader writer lock object guarantees that the order of exclusive (writer) lock-ownership is on a first-come, first-serve basis.
  • There is no need to explicitly call Initialization of resources before use of the concurrency runtime’s reader writer lock and release after the use of the reader writer lock.
  • Cannot specify spin count for the concurrency runtime’s reader writer lock object.
  • The concurrency runtime’s reader writer lock enforces cooperative blocking where they yield to other cooperative tasks in the runtime when blocked.
  • The concurrency runtime’s reader writer locks give writer preference over readers; i.e. if there are readers and writer(s) simultaneously waiting for the lock, the lock would be handed over to the first writer in queue.
  • Exceptions are thrown by the concurrency runtime’s reader writer lock object; on recursive calls, or if unlock is called when the lock is not held, or if a lock is destroyed when being held.