|< Windows Processes & Threads: Synchronization 2 | Main | Windows Processes & Threads: Synchronization 4 >| Site Index | Download |


 

 

 

 

 

 

 

MODULE V2

PROCESSES AND THREADS: SYNCHRONIZATION

Part 3: STORY

 

 

 

 

 

What do we have in this Module?

  1. Interprocess Synchronization

  2. Object Names

  3. Object Inheritance

  4. Object Duplication

  5. Synchronization Object Security and Access Rights

  6. Synchronization Reference

  7. Synchronization Functions

  8. Synchronization Structures

  9. Synchronization Macros

 

 

 

 

 

 

 

 

 

 

 

 

 

My Training Period: xx hours. Before you begin, read some instruction here.

 

The expected abilities for this session are:

Interprocess Synchronization

 

In network and distributed computing there are more processes and threads need to be managed.  This includes synchronization among processes.  Multiple processes can have handles to the same event, mutex, semaphore, or timer object, so these objects can be used to accomplish interprocess synchronization. The process that creates an object can use the handle returned by the creation function (CreateEvent(), CreateMutex(), CreateSemaphore(), or CreateWaitableTimer()). Other processes can open a handle to the object by using its name, or through inheritance or duplication.

 

Object Names

 

Named objects provide an easy way for processes to share object handles. Once a process has created a named event, mutex, semaphore, or timer object, other processes can use the name to call the appropriate function (OpenEvent(), OpenMutex(), OpenSemaphore(), or OpenWaitableTimer()) to open a handle to the object. Name comparison is case sensitive.

The names of event, semaphore, mutex, waitable timer, file-mapping, and job objects share the same name space. If you try to create an object using a name that is in use by an object of another type, the function fails and GetLastError() returns ERROR_INVALID_HANDLE. Therefore, when creating named objects, use unique names and be sure to check function return values for duplicate-name errors.

If you try to create an object using a name that is in use by an object of same type, the function succeeds, returning a handle to the existing object, and GetLastError() returns ERROR_ALREADY_EXISTS. For example, if the name specified in a call to the CreateMutex() function matches the name of an existing mutex object, the function returns a handle to the existing object. In this case, the call to CreateMutex() is equivalent to a call to the OpenMutex() function. Having multiple processes use CreateMutex() for the same mutex is therefore equivalent to having one process that calls CreateMutex() while the other processes call OpenMutex(), except that it eliminates the need to ensure that the creating process is started first. When using this technique for mutex objects, however, none of the calling processes should request immediate ownership of the mutex. If multiple processes do request immediate ownership, it can be difficult to predict which process actually gets the initial ownership.

For Terminal Services:  A Terminal Services environment has a global name space for events, semaphores, mutexes, waitable timers, file-mapping objects, and job objects. In addition, each Terminal Services client session has its own separate name space for these objects. Terminal Services client processes can use object names with a "Global\" or "Local\" prefix to explicitly create an object in the global or session name space.

For Windows XP Home Edition:  Fast user switching is implemented using Terminal Services sessions. The first user to log on uses session 0, the next user to log on uses session 1, and so on. Kernel object names must follow the guidelines outlined for Terminal Services so that applications can support multiple users. For Windows 2000:  If Terminal Services is not running, the "Global\" and "Local\" prefixes are ignored. The remainder of the name can contain any character except the backslash character. For Windows NT 4.0 and earlier:  The name can contain any character except the backslash character. For Windows Me/98/95:  The name can contain any character except the backslash character. The empty string ("") is a valid object name.

 

 

Object Inheritance

 

When you create a process with the CreateProcess() function, you can specify that the process inherit handles to mutex, event, semaphore, or timer objects using the SECURITY_ATTRIBUTES structure. The handle inherited by the process has the same access to the object as the original handle. The inherited handle appears in the handle table of the created process, but you must communicate the handle value to the created process. You can do this by specifying the value as a command-line argument when you call CreateProcess(). The created process then uses the GetCommandLine() function to retrieve the command-line string and convert the handle argument into a usable handle.

 

Object Duplication

 

The DuplicateHandle() function creates a duplicate handle that can be used by another specified process. This method of sharing object handles is more complex than using named objects or inheritance. It requires communication between the creating process and the process into which the handle is duplicated. The necessary information (the handle value and process identifier) can be communicated by any of the interprocess communication methods, such as named pipes or named shared memory.

 

Synchronization Object Security and Access Rights

 

The Windows security model enables you to control access to event, mutex, semaphore, and waitable timer objects. Timer queues, interlocked variables, and critical section objects are not securable. You can specify a security descriptor for an interprocess synchronization object when you call the CreateEvent(), CreateMutex(), CreateSemaphore(), or CreateWaitableTimer() function. If you specify NULL, the object gets a default security descriptor. The ACLs in the default security descriptor for a synchronization object come from the primary or impersonation token of the creator.

To get or set the security descriptor of an event, mutex, semaphore, or waitable timer object, call the GetNamedSecurityInfo(), SetNamedSecurityInfo(), GetSecurityInfo(), or SetSecurityInfo() functions. The handles returned by CreateEvent(), CreateMutex(), CreateSemaphore(), and CreateWaitableTimer() have full access to the new object. When you call the OpenEvent(), OpenMutex(), OpenSemaphore(), and OpenWaitableTimer() functions, the system checks the requested access rights against the object's security descriptor. The valid access rights for all interprocess synchronization objects include the DELETE, READ_CONTROL, SYNCHRONIZE, WRITE_DAC, and WRITE_OWNER standard access rights.  The following table lists the specific access rights for event objects.

 

Value

Meaning

EVENT_ALL_ACCESS

All possible access rights for an event object.

EVENT_MODIFY_STATE

Modify state access, which is required for the SetEvent(), ResetEvent() and PulseEvent() functions.

 

Table 7

 

The following table lists the specific access rights for mutex objects.

 

Value

Meaning

MUTEX_ALL_ACCESS

All possible access rights for a mutex object.

MUTEX_MODIFY_STATE

Modify state access, which is required for the ReleaseMutex() function.

 

Table 8

 

The following table lists the specific access rights for semaphore objects.

 

Value

Meaning

SEMAPHORE_ALL_ACCESS

All possible access rights for a semaphore object.

SEMAPHORE_MODIFY_STATE

Modify state access, which is required for the ReleaseSemaphore() function.

 

Table 9

 

The following table lists the specific access rights for waitable timer objects.

 

Value

Meaning

TIMER_ALL_ACCESS

All possible access rights for a waitable timer object.

TIMER_MODIFY_STATE

Modify state access, which is required for the SetWaitableTimer() and CancelWaitableTimer() functions.

TIMER_QUERY_STATE

Reserved for future use.

 

Table 10

 

To read or write the SACL of an interprocess synchronization object, you must request the ACCESS_SYSTEM_SECURITY access right.

 

Synchronization Reference

 

The following functions, structures and macros are used with synchronization.

 

Synchronization Functions

 

The following functions are used in synchronization.

 

Asynchronous function

Description

APCProc()

An application-defined callback function used with the QueueUserAPC() function.

GetOverlappedResult()

Retrieves the results of an overlapped operation.

QueueUserAPC()

Adds a user-mode asynchronous procedure call (APC) object to the APC queue of the specified thread.

 

Table 11

 

 

Critical-section function

Description

DeleteCriticalSection()

Releases all resources used by an unowned critical section object.

EnterCriticalSection()

Waits for ownership of the specified critical section object.

InitializeCriticalSection()

Initializes a critical section object.

InitializeCriticalSectionAndSpinCount()

Initializes a critical section object and sets the spin count for the critical section.

LeaveCriticalSection()

Releases ownership of the specified critical section object.

SetCriticalSectionSpinCount()

Sets the spin count for the specified critical section.

TryEnterCriticalSection()

Attempts to enter a critical section without blocking.

 

Table 12

 

 

Event function

Description

CreateEvent()

Creates or opens a named or unnamed event object.

OpenEvent()

Opens an existing named event object.

PulseEvent()

Sets the specified event object to the signaled state and then resets it to the non-signaled state after releasing the appropriate number of waiting threads.

ResetEvent()

Sets the specified event object to the non-signaled state.

SetEvent()

Sets the specified event object to the signaled state.

 

Table 13

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Interlocked function

Description

InterlockedCompareExchange()

Performs an atomic comparison of the specified values and exchanges the values, based on the outcome of the comparison.

InterlockedCompareExchange64()

Functions identically to InterlockedCompareExchange() except that operations are performed on 64-bit values.

InterlockedCompareExchangeAcquire()

Functions identically to InterlockedCompareExchange() except that acquire memory access semantics are used in the exchange operation.

InterlockedCompareExchangeAcquire64()

Functions identically to InterlockedCompareExchangeAcquire() except that operations are performed on 64-bit values and addresses.

InterlockedCompareExchangePointer()

Performs an atomic comparison of the specified values and exchange of the values, based on the outcome of the comparison.

InterlockedCompareExchangeRelease()

Functions identically to InterlockedCompareExchange() except that release memory access semantics are used in the exchange operation.

InterlockedCompareExchangeRelease64()

Functions identically to InterlockedCompareExchangeRelease() except that operations are performed on 64-bit values and addresses.

InterlockedDecrement()

Decrements (decreases by one) the value of the specified variable and checks the resulting value.

InterlockedDecrement64()

Functions identically to InterlockedDecrement() except that operations are performed on 64-bit values and addresses.

InterlockedDecrementAcquire()

Functions identically to InterlockedDecrement() except that acquire memory access semantics are used in the exchange operation.

InterlockedDecrementRelease()

Functions identically to InterlockedDecrement() except that release memory access semantics are used in the exchange operation.

InterlockedExchange()

Atomically exchanges a pair of values.

InterlockedExchangeAcquire64()

Functions identically to InterlockedExchange() except that acquire memory access semantics are used in the exchange operation and it processes 64-bit values and addresses.

InterlockedExchangeAdd()

Performs an atomic addition of an increment value to an addend variable.

InterlockedExchangePointer()

Atomically exchanges a pair of values.

InterlockedFlushSList()

Removes all items from a singly linked list.

InterlockedIncrement()

Increments (increases by one) the value of the specified variable and checks the resulting value.

InterlockedIncrement64()

Functions identically to InterlockedIncrement() except that operations are performed on 64-bit values and addresses.

InterlockedIncrementAcquire()

Functions identically to InterlockedIncrement() except that acquire memory access semantics are used in the exchange operation.

InterlockedIncrementRelease()

Functions identically to InterlockedIncrement() except that release memory access semantics are used in the exchange operation.

InterlockedPopEntrySList()

Removes an item from the front of a singly linked list.

InterlockedPushEntrySList()

Inserts an item at the front of a singly linked list.

 

Table 14

 

 

Mutex function

Description

CreateMutex()

Creates or opens a named or unnamed mutex object.

OpenMutex()

Opens an existing named mutex object.

ReleaseMutex()

Releases ownership of the specified mutex object.

 

Table 15

 

 

Semaphore function

Description

CreateSemaphore()

Creates or opens a named or unnamed semaphore object.

OpenSemaphore()

Opens an existing named semaphore object.

ReleaseSemaphore()

Increases the count of the specified semaphore object by a specified amount.

 

Table 16

 

 

Singly-linked list function

Description

InitializeSListHead()

Initializes the head of a singly linked list.

InterlockedFlushSList()

Flushes the entire list of items in a singly linked list.

InterlockedPopEntrySList()

Removes an item from the front of a singly linked list.

InterlockedPushEntrySList()

Inserts an item at the front of a singly linked list.

 

Table 17

 

 

Timer-queue timer function

Description

ChangeTimerQueueTimer()

Updates a timer-queue timer.

CreateTimerQueue()

Creates a queue for timers.

CreateTimerQueueTimer()

Creates a timer-queue timer.

DeleteTimerQueue()

Deletes a timer queue.

DeleteTimerQueueEx()

Deletes a timer queue.

DeleteTimerQueueTimer()

Cancels a timer-queue timer.

 

Table 18

 

 

Wait function

Description

MsgWaitForMultipleObjects()

Returns when the specified criterion for the specified objects is met.

MsgWaitForMultipleObjectsEx()

Returns when the specified criterion for the specified objects is met.

RegisterWaitForSingleObject()

Directs a wait thread in the thread pool to wait on the object.

SignalObjectAndWait()

Allows the caller to atomically signal an object and wait on another object.

UnregisterWait()

Cancels a registered wait operation.

UnregisterWaitEx()

Cancels a registered wait operation.

WaitForMultipleObjects()

Returns when the specified criterion for the specified objects is met.

WaitForMultipleObjectsEx()

Returns when the specified criterion for the specified objects is met.

WaitForSingleObject()

Returns when the specified criterion for the specified object is met.

WaitForSingleObjectEx()

Returns when the specified criterion for the specified object is met.

WaitOrTimerCallback()

Returns when the specified criterion is met.

 

Table 19

 

 

Waitable-timer function

Description

CancelWaitableTimer()

Sets the specified waitable timer to the inactive state.

CreateWaitableTimer()

Creates or opens a waitable timer object.

OpenWaitableTimer()

Opens an existing named waitable timer object.

SetWaitableTimer()

Activates the specified waitable timer.

TimerAPCProc()

Application-defined timer completion routine used with the SetWaitableTimer() function.

 

Table 20

 

Synchronization Structures

 

The following structures are used with synchronization: OVERLAPPED and SLIST_ENTRY.

 

Synchronization Macros

 

The following macros are used with synchronization: HasOverlappedIoCompleted(), MemoryBarrier(), PreFetchCacheLine() and YieldProcessor().

 

 

 

----------------End of Windows process Synchronization Story-------------------

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Further reading and digging:

 

  1. For Multibytes, Unicode characters and Localization please refer to Locale, wide characters & Unicode (Story) and Windows users & groups programming tutorials (Implementation).

  2. Structure, enum, union and typedef story can be found C/C++ struct, enum, union & typedef.

  3. Microsoft Visual C++, online MSDN.

  4. Check the best selling C / C++ and Windows books at Amazon.com.

  5. Unicode version of the Win32 programming tutorials and more details windows process, threads and synchronization.

 

 

 

 

 

 

 

 

|< Windows Processes & Threads: Synchronization 2 | Main | Windows Processes & Threads: Synchronization 4 >| Site Index | Download |