| Home | Libraries | People | FAQ | More

## Some basic explanations

### Processes And Threads

Boost.Interprocess does not work only with processes but also with threads. Boost.Interprocess synchronization mechanisms can synchronize threads from different processes, but also threads from the same process.

### Sharing information between processes

In the traditional programming model an operating system has multiple processes running and each process has its own address space. To share information between processes we have several alternatives:

- Two processes share information using a file. To access to the data, each process uses the usual file read/write mechanisms. When updating/reading a file shared between processes, we need some sort of synchronization, to protect readers from writers.
- Two processes share information that resides in the kernel of the operating system. This is the case, for example, of traditional message queues. The synchronization is guaranteed by the operating system kernel.
- Two processes can share a memory region. This is the case of classical shared memory or memory mapped files. Once the processes set up the memory region, the processes can read/write the data like any other memory segment without calling the operating system's kernel. This also requires some kind of manual synchronization between processes.

### Persistence Of Interprocess Mechanisms

One of the biggest issues with interprocess communication mechanisms is the lifetime of the interprocess communication mechanism. It's important to know when an interprocess communication mechanism disappears from the system. In Boost.Interprocess, we can have 3 types of persistence:

- Process-persistence: The mechanism lasts until all the processes that have opened the mechanism close it, exit or crash.
- Kernel-persistence: The mechanism exists until the kernel of the operating system reboots or the mechanism is explicitly deleted.
- Filesystem-persistence: The mechanism exists until the mechanism is explicitly deleted.

Some native POSIX and Windows IPC mechanisms have different persistence so it's difficult to achieve portability between Windows and POSIX native mechanisms. Boost.Interprocess classes have the following persistence:

Table 14.1. Boost.Interprocess Persistence Table

Mechanism | Persistence
--- | ---
Shared memory | Kernel or Filesystem
Memory mapped file | Filesystem
Process-shared mutex types | Process
Process-shared semaphore | Process
Process-shared condition | Process
File lock | Process
Message queue | Kernel or Filesystem
Named mutex | Kernel or Filesystem
Named semaphore | Kernel or Filesystem
Named condition | Kernel or Filesystem

As you can see, Boost.Interprocess defines some mechanisms with "Kernel or Filesystem" persistence. This is because POSIX allows this possibility to native interprocess communication implementations. One could, for example, implement shared memory using memory mapped files and obtain filesystem persistence (for example, there is no proper known way to emulate kernel persistence with a user library for Windows shared memory using native shared memory, or process persistence for POSIX shared memory, so the only portable way is to define "Kernel or Filesystem" persistence).

### Names Of Interprocess Mechanisms

Some interprocess mechanisms are anonymous objects created in shared memory or memory-mapped files but other interprocess mechanisms need a name or identifier so that two unrelated processes can use the same interprocess mechanism object. Examples of this are shared memory, named mutexes and named semaphores (for example, native windows CreateMutex/CreateSemaphore API family).

The name used to identify an interprocess mechanism is not portable, even between UNIX systems. For this reason, Boost.Interprocess limits this name to a C++ variable identifier or keyword:

- Starts with a letter, lowercase or uppercase, such as a letter from a to z or from A to Z. Examples: Sharedmemory, sharedmemory, sHaReDmEmOrY...
- Can include letters, underscore, or digits. Examples: shm1, shm2and3, ShM3plus4...

### Constructors, destructors and lifetime of Interprocess named resources

Named Boost.Interprocess resources (shared memory, memory mapped files, named mutexes/conditions/semaphores) have kernel or filesystem persistency. This means that even if all processes that have opened those resources end, the resource will still be accessible to be opened again and the resource can only be destructed via an explicit to their static member `remove` function. This behavior can be easily understood, since it's the same mechanism used by functions controlling file opening/creation/erasure:

Table 14.2. Boost.Interprocess-Filesystem Analogy

Named Interprocess resource | Corresponding std file | Corresponding POSIX operation
--- | --- | ---
Constructor | std::fstream constructor | open
Destructor | std::fstream destructor | close
Member `remove` | None. `std::remove` | unlink

Now the correspondence between POSIX and Boost.Interprocess regarding shared memory and named semaphores:

Table 14.3. Boost.Interprocess-POSIX shared memory

`shared_memory_object` operation | POSIX operation
--- | ---
Constructor | shm_open
Destructor | close
Member `remove` | shm_unlink

Table 14.4. Boost.Interprocess-POSIX named semaphore

`named_semaphore` operation | POSIX operation
--- | ---
Constructor | sem_open
Destructor | close
Member `remove` | sem_unlink

The most important property is that destructors of named resources don't remove the resource from the system, they only liberate resources allocated by the system for use by the process for the named resource. To remove the resource from the system the programmer must use `remove`.

### Permissions

Named resources offered by Boost.Interprocess must cope with platform-dependant permission issues also present when creating files. If a programmer wants to shared shared memory, memory mapped files or named synchronization mechanisms (mutexes, semaphores, etc...) between users, it's necessary to specify those permissions. Sadly, traditional UNIX and Windows permissions are very different and Boost.Interprocess does not try to standardize permissions, but does not ignore them.

All named resource creation functions take an optional `permissions object` that can be configured with platform-dependant permissions.

Since each mechanism can be emulated through diferent mechanisms (a semaphore might be implement using mapped files or native semaphores) permissions types could vary when the implementation of a named resource changes (eg.: in Windows mutexes require `synchronize permissions`, but that's not the case of files). To avoid this, Boost.Interprocess relies on file-like permissions, requiring file read-write-delete permissions to open named synchronization mechanisms (mutex, semaphores, etc.) and appropiate read or read-write-delete permissions for shared memory. This approach has two advantages: it's similar to the UNIX philosophy and the programmer does not need to know how the named resource is implemented.