Semaphores
Apart from kernel objects that enable you to provide mutually exclusive access to resources within a process and between processes, Windows Embedded CE also provides semaphore objects that enable concurrent access to a resource by one or multiple threads. These semaphore objects maintain a counter between zero and a maximum value to control the number of threads accessing the resource. The maximum value amount is specified in the CreateSemaphore function call.
The semaphore counter limits the number of threads that can access the synchronization object concurrently. The system will keep decrementing the counter every time a thread completes a wait for the semaphore object until the counter reaches zero and enters the nonsignaled state. The counter cannot decrement past zero. No further thread can gain access to the resource until an owning thread releases the semaphore by calling the ReleaseSemaphore function, which increments the counter by a specified value and again switches the semaphore object back into signaled state.
Similar to mutexes, multiple processes can open handles of the same semaphore object to access resources shared between processes. The first call to the CreateSemaphore function creates the semaphore object with a specified name. You can also construct unnamed semaphores, but these objects are not available for interprocess synchronization. Subsequent calls to the CreateSemaphore function with the same semaphore name do not create new objects, but open a new handle of the same semaphore.
Table 3-13 lists the most important functions that work with semaphore objects for thread synchronization purposes.
Table 3-13 Semaphore API
Function | Description |
---|---|
CreateSemaphore | Creates and initializes a named or unnamed semaphore object with a counter value. Use named semaphore objects to protect resources shared between processes. |
CloseHandle | Closes a semaphore handle and deletes the reference to the semaphore object. All references to the semaphore must be closed individually before the kernel deletes the semaphore object. |
WaitForSingleObject | Waits to be granted ownership of a single semaphore object. |
WaitForMultipleObjects | Waits to be granted ownership for a single or multiple semaphore objects. |
ReleaseSemaphore | Releases a semaphore object. |
Events
The Event object is another kernel object that synchronizes threads. This object enables applications to signal other threads when a task is finished or when data is available to potential readers. Each event has signaled/non-signaled state information used by the API to identify the state of the event. Two types of events, manual events and auto-reset events, are created according to the behavior expected by the event.
The creating thread specifies a name for the event object at creation time, although it is also possible to create an unnamed event. It is possible for threads in other processes to call CreateMutex and specify the same name, but these subsequent calls do not create new kernel objects.
Table 3-14 lists the most important functions for event objects for thread synchronization purposes.
Table 3-14 Event API
Function | Description |
---|---|
CreateEvent | Creates and initializes a named or unnamed event object. |
SetEvent | Signal an event (see below). |
PulseEvent | Pulse and signal the event (see below). |
ResetEvent | Reset a signaled event. |
WaitForSingleObject | Waits for an event to be signaled. |
WaitForMultipleObjects | Waits to be signaled by a single or multiple event objects. |
CloseHandle | Releases an Event object. |