CSemaphore Class
The latest version of this topic can be found at CSemaphore Class.
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.
Syntax
class CSemaphore : public CSyncObject
Members
Public Constructors
Name | Description |
---|---|
CSemaphore::CSemaphore | Constructs a CSemaphore object. |
Remarks
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.
Inheritance Hierarchy
CSemaphore
Requirements
Header: afxmt.h
CSemaphore::CSemaphore
Constructs a named or unnamed CSemaphore
object.
CSemaphore(
LONG lInitialCount = 1,
LONG lMaxCount = 1,
LPCTSTR pstrName = NULL,
LPSECURITY_ATTRIBUTES lpsaAttributes = NULL);
Parameters
lInitialCount
The initial usage count for the semaphore. Must be greater than or equal to 0, and less than or equal to lMaxCount
.
lMaxCount
The maximum usage count for the semaphore. Must be greater than 0.
pstrName
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.
lpsaAttributes
Security attributes for the semaphore object. For a full description of this structure, see SECURITY_ATTRIBUTES in the Windows SDK.
Remarks
To access or release a CSemaphore
object, create a CMultiLock or CSingleLock object and call its Lock and Unlock member functions.
Important
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.