January 21, 2021
Hot Topics:

Native Parallel Programming for Visual C++: State Management

  • By Nick Wienholt
  • Send Email »
  • More Articles »


The use of combinable is dependent on one task not needing the results of processing on other tasks. In cases where multiple tasks need to share an object, you must use more traditional synchronization strategies. The PPL ships with three synchronization primitives – critical_section, reader_writer_lock and event. A critical_section locks a memory location against access for all tasks that do not hold the lock. For memory locations that will have many simultaneous readers and fewer writers, the more optimized reader_writer_lock is available, which allows multiple readers to acquire the lock and access the memory location concurrently. The final primitive is event, which is used to signal between tasks and threads.

The synchronization primitives are defined in the concrt.h header file—the base header file for the PPL (included in ppl.h). Most of the types defined in concrt.h are targeted more toward library authors rather than application developers, but anyone interested in deeper-level concurrency development is free to investigate and use appropriate features from the exposed types.

The API of the critical_section type is extremely simple; you use a blocking lock method to acquire the lock, a non-blocking try_lock is to attempt to acquire the lock if it is available, and unlock to release a locked critical_section.

The reader_writer_lock is only marginally more complex. It adds two methods, lock_read and try_lock_read that support acquiring a reader lock. The unlock method remains the same as critical_section, and will release the appropriate lock based on the type of lock that is being held.

The final synchronization primitive is event, which represents a manual reset event (i.e. the event stays set until it is manually reset by external code). Code can wait for a single event to be set by calling the instance wait method, which also supports an optional timeout value. When no timeout is specified, the wait time is infinite. You can wait on multiple events by using the static wait_for_multiple, which accepts a C-style array of event pointers. The wait_for_multiple method waits for either a single event or for all the events passed into the method call. The code below waits for both events to be set:

event* events[2];
events[0] = new event();
events[1] = new event();
[&]{ events[0]->set(); },                             
[&]{ events[1]->set(); } 
bool waitForAllEvents = true;
event::wait_for_multiple(events, 2, waitForAllEvents);

Dealing with state management when executing tasks concurrently is a notoriously difficult undertaking. The PPL provides support for a pattern of state management where each thread operates on a local version of the shared object, with the results combined together at the completion of processing. For scenarios where segregated state management is not appropriate, the PPL provides traditional synchronization primitives in the form of critical sections, reader writer locks and events.

About the Author

Nick Wienholt is an independent Windows and .NET consultant based in Sydney. He is the author of Maximizing .NET Performance and co-author of A Programmer's Introduction to C# 2.0, from Apress, and specializes in system-level software architecture and development, with a particular focus on performance, security, interoperability, and debugging.

Nick is a keen and active participant in the .NET community. He is the co-founder of the Sydney Deep .NET User group and writes technical articles for the Australian Developer Journal, ZDNet, Pinnacle Publishing, CodeGuru, MSDN Magazine (Australia and New Zealand Edition) and the Microsoft Developer Network. In recognition of his work in the .NET area, Nick was awarded the Microsoft Most Valued Professional Award from 2002 through 2007.

Page 2 of 2

This article was originally published on June 2, 2009

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date