Interprocess Synchronization

Because multiple processes can have handles to the same event or mutex object, 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 or CreateMutex. Other processes can open a handle to the object by using its name in another call to the appropriate creation function.

Named objects provide an easy way for processes to share object handles. The name specified by the creating process is limited to the number of characters defined by MAX_PATH. It can include any character except the backslash path-separator character (\). Once a process has created a named event or mutex object, other processes can use the name to call the appropriate function, either CreateEvent or CreateMutex, to open a handle to the object. Name comparison is case-sensitive.

The names of event and mutex objects share the same name space. If you specify a name that is in use by an object of another type when you create an object, the function succeeds, but GetLastError returns ERROR_ALREADY_EXISTS. To avoid this error, use unique names and be sure to check function-return values for duplicate-name errors.

If the name specified in a call to CreateEvent matches the name of an existing event object, the function returns the handle of the existing object. When using this technique for event objects, however, none of the calling processes should request immediate ownership of the event. If multiple processes do request immediate ownership, you may have difficulty predicting which process will get the initial ownership.

The following code examples illustrate the use of object names by creating and opening named objects. The first process uses the CreateMutex function to create the mutex object. Note that the function succeeds even if there is an existing object with the same name.

HANDLE hMutex; 
DWORD dwErr; 

hMutex = CreateMutex
      ( 
      NULL,                           // no security descriptor
      FALSE,                          // mutex not owned
      "NameOfMutexObject");           // object name

if (hMutex == NULL) 
      printf("CreateMutex error: %d\n", GetLastError() ); 
else 
      if ( GetLastError() == ERROR_ALREADY_EXISTS ) 
         printf("CreateMutex opened existing mutex\n"); 
      else 
         printf("CreateMutex created new mutex\n"); 

The second process uses the CreateMutex function to open a handle of the existing mutex.

HANDLE hMutex; 

hMutex = OpenMutex
      ( 
      MUTEX_ALL_ACCESS,               // request full access
      FALSE,                          // handle not inheritable
      "NameOfMutexObject");           // object name

if (hMutex == NULL) 
      printf("OpenMutex error: %d\n", GetLastError() );