Table 3-12 lists the most important functions that you can use to work with mutex objects for thread synchronization purposes.
Table 3-12 Mutex API
Function | Description |
---|---|
CreateMutex | Create and initialize a named or unnamed mutex object. To protect resources shared between processes, you must use named mutex objects. |
CloseHandle | Closes a mutex handle and deletes the reference to the mutex object. All references to the mutex must be deleted individually before the kernel deletes the mutex object. |
WaitForSingleObject | Waits to be granted ownership of a single mutex object. |
WaitForMultipleObjects | Waits to be granted ownership for a single or multiple mutex objects. |
ReleaseMutex | Releases a mutex object. |
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. |
The behavior of the events API is different according to the type of events. When you use SetEvent on a manual event object, the event will stay signaled until ResetEvent is explicitly called. Auto-reset events only stay signaled until a single waiting thread is released. At most, one waiting thread is released when using the PulseEvent function on auto-reset events before it immediately transitions back to the non-signaled state. In the case of manual threads, all waiting threads are released and immediately transition back to a non-signaled state.
Interlocked Functions
In multithread environments, threads can be interrupted at any time and resumed later by the scheduler. Portions of code or applications resources can be protected using semaphores, events, or critical sections. In some applications, it could be too time consuming to use those kinds of system objects to protect only one line of code like this: