Multithreading: When to Use the Synchronization Classes
The six multithreaded classes provided with MFC fall into two categories: synchronization objects (CSyncObject, CSemaphore, CMutex, CCriticalSection, and CEvent) and synchronization access objects (CMultiLock and CSingleLock).
Synchronization classes are used when access to a resource must be controlled to ensure integrity of the resource. Synchronization access classes are used to gain access to these controlled resources. This article describes when to use each class.
To determine which synchronization class you should use, ask the following series of questions:
- Does the application have to wait for something to happen before it can access the resource (for example, data must be received from a communications port before it can be written to a file)?
If yes, use CEvent.
- Can more than one thread within the same application access this resource at one time (for example, your application allows up to five windows with views on the same document)?
If yes, use CSemaphore.
- Can more than one application use this resource (for example, the resource is in a DLL)?
If yes, use CMutex.
If no, use CCriticalSection.
CSyncObject is never used directly. It is the base class for the other four synchronization classes.
Example 1: Using Three Synchronization Classes
As an example, take an application that maintains a linked list of accounts. This application allows up to three accounts to be examined in separate windows, but only one can be updated at any particular time. When an account is updated, the updated data is sent over the network to a data archive.
This example application uses all three types of synchronization classes. Because it allows up to three accounts to be examined at one time, it uses CSemaphore to limit access to three view objects. When an attempt to view a fourth account occurs, the application either waits until one of the first three windows closes or it fails. When an account is updated, the application uses CCriticalSection to ensure that only one account is updated at a time. After the update succeeds, it signals CEvent, which releases a thread waiting for the event to be signaled. This thread sends the new data to the data archive.
Example 2: Using Synchronization Access Classes
Choosing which synchronization access class to use is even simpler. If your application is concerned with accessing a single controlled resource only, use CSingleLock. If it needs access to any one of a number of controlled resources, use CMultiLock. In example 1, CSingleLock would have been used, as in each case only one resource was needed at any particular time.
For information on how the synchronization classes are used, see the article Multithreading: How to Use the Synchronization Classes. For more information on synchronization, see Synchronization in the Platform SDK. For more information on multithreading support in MFC, see the article Multithreading with C++ and MFC.