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.
class CSemaphore : public CSyncObject
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
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.
Constructs a named or unnamed
CSemaphore( LONG lInitialCount = 1, LONG lMaxCount = 1, LPCTSTR pstrName = NULL, LPSECURITY_ATTRIBUTES lpsaAttributes = NULL);
The initial usage count for the semaphore. Must be greater than or equal to 0, and less than or equal to lMaxCount.
The maximum usage count for the semaphore. Must be greater than 0.
The name of the semaphore. Must be supplied if the semaphore will be accessed across process boundaries. If
NULL, the object will be unnamed. If the name matches an existing semaphore, the constructor builds a new
CSemaphore object which references the semaphore of that name. If the name matches an existing synchronization object that is not a semaphore, the construction will fail.
Security attributes for the semaphore object. For a full description of this structure, see SECURITY_ATTRIBUTES in the Windows SDK.
After creating the
CSemaphore object, use GetLastError to ensure that the mutex did not already exist. If the mutex did exist unexpectedly, it may indicate a rogue process is squatting and may be intending to use the mutex maliciously. In this case, the recommended security-conscious procedure is to close the handle and continue as if there was a failure in creating the object.