Getting Started with Cbeam’s Interprocess Containers

Overview

One of the standout features of Cbeam is its platform-independent approach to interprocess data sharing. Whether you're passing information across multiple processes or simply offloading certain tasks between libraries, Cbeam provides three key classes to keep your data consistent, safe, and synchronized:

  • interprocess_shared_memory A low-level, cross-platform wrapper for shared memory segments. It seamlessly handles platform-specific details, ensuring that shared memory automatically cleans up once no process needs it. This avoids file-permission issues and reduces the hassle of manually destroying shared memory on both Windows and POSIX systems.

  • stable_interprocess_container A base class that extends interprocess_shared_memory by adding stable serialization capabilities. Its design ensures that complex data structures remain reliable even if they need to be accessed by different libraries or compiler versions. You can derive specialized containers from this class, reusing its robust concurrency and serialization logic.

  • stable_interprocess_map A ready-to-use map container derived from stable_interprocess_container, storing key-value pairs in shared memory. It keeps data stable and consistent, supporting concurrent insertions, lookups, and updates with minimal fuss.

Example

Here’s a short demo with two processes that share the same stable_interprocess_map. The first process inserts data into the map, and the second one retrieves it. (We skip error handling and advanced serialization details for brevity.)

// main1.cpp
#include <iostream>
#include <cbeam/container/stable_interprocess_map.hpp>

int main()
{
    // Create or open a shared map with the unique ID "mySharedMap" and a fixed size.
    // The size must be sufficient for the serialized data.
    cbeam::container::stable_interprocess_map<int, std::string> sharedMap("mySharedMap", 1024);

    // Insert a simple key-value pair
    sharedMap.insert(42, "Hello from Process 1");

    std::cout << "Process 1 inserted key=42" << std::endl;
    return 0;
}
// main2.cpp
#include <iostream>
#include <cbeam/container/stable_interprocess_map.hpp>

int main()
{
    // Access the same shared map
    cbeam::container::stable_interprocess_map<int, std::string> sharedMap("mySharedMap", 1024);

    // Retrieve the value associated with key=42
    std::string value = sharedMap.at(42);
    std::cout << "Process 2 read: key=42, value=" << value << std::endl;
    return 0;
}

Compile and run these two executables in separate processes. Thanks to Cbeam’s interprocess functionality, the second process will see the data inserted by the first one.

Details

Under the hood, stable_interprocess_map inherits from stable_interprocess_container, which itself leverages interprocess_shared_memory. This layered design keeps shared data stable (to handle different compiler ABIs), while providing a clean interface for concurrency. By changing just a few lines, you can build your own "stable" containers on top of stable_interprocess_container or directly use the low-level interprocess_shared_memory class if you need more fine-grained control.

Summary

These three classes—interprocess_shared_memory, stable_interprocess_container, and stable_interprocess_map—are central to Cbeam’s unique approach to interprocess collaboration. Beyond maps, you can craft custom containers or even integrate your own serialization logic to simplify complex data exchange across multiple libraries and processes.