|Important||This document may not represent best practices for current development, links to downloads and other resources may no longer be valid. Current recommended version can be found here. ArchiveDisclaimer|
An object of class CSemaphore represents a "semaphore" — a synchronization object that allows a limited number of threads in one or more processes to access a Maintains a count of the number of threads currently accessing a specified resource.
Semaphores are useful in controlling access to a shared resource that can only support a limited number of users. The current count of the CSemaphore object is the number of additional users allowed. When the count reaches zero, all attempts to use the resource controlled by the CSemaphore object will be inserted into a system queue and wait until they either time out or the count rises above 0. The maximum number of users who can access the controlled resource at one time is specified during construction of the CSemaphore object.
To use a CSemaphore object, construct the CSemaphore object when it is needed. Specify the name of the semaphore you wish to wait on, and that your application should initially own it. You can then access the semaphore when the constructor returns. Call CSyncObject::Unlock when you are done accessing the controlled resource.
An alternative method for using CSemaphore objects is to add a variable of type CSemaphore as a data member to the class you wish to control. During construction of the controlled object, call the constructor of the CSemaphore data member specifying the initial access count, maximum access count, name of the semaphore (if it will be used across process boundaries), and desired security attributes.
To access resources controlled by CSemaphore objects in this manner, first create a variable of either type CSingleLock or type CMultiLock in your resource's access member function. Then call the lock object's Lock member function (for example, CSingleLock::Lock). At this point, your thread will either gain access to the resource, wait for the resource to be released and gain access, or wait for the resource to be released and time out, failing to gain access to the resource. In any case, your resource has been accessed in a thread-safe manner. To release the resource, use the lock object's Unlock member function (for example, CSingleLock::Unlock), or allow the lock object to fall out of scope.
Alternatively, you can create a CSemaphore object stand-alone, and access it explicitly before attempting to access the controlled resource. This method, while clearer to someone reading your source code, is more prone to error.
For more information on how to use CSemaphore objects, see the article Multithreading: How to Use the Synchronization Classes.