This project demonstrates uni-directional data transfer of large arrays between two Docker containers using shared memory (shmem).
- Source Container: C++ application that writes data to shared memory
- Destination Container: Python application that reads data from shared memory
- Transport: POSIX shared memory for high-performance data transfer
haidis-connectors/
├── source/ # C++ source container (CMake)
├── destination/ # Python destination container (uv)
└── shared/ # Shared configuration
- Docker
- Docker Compose
# Build and start both containers
docker-compose up --build
# Stop containers
docker-compose downBuilt with CMake. The build produces two artifacts:
libshmem_writer.a— a standalone static library containing theShmemWriterclass, which can be linked into other applicationsshmem_source— the demo executable that links against the library
cd source
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build buildTo install the library and headers to a prefix (e.g., /usr/local):
cmake --install build --prefix /usr/localThis installs:
lib/libshmem_writer.a— the static libraryinclude/shmem_writer.hpp— the headerlib/cmake/shmem_writer/— CMake config files forfind_package(shmem_writer)bin/shmem_source— the demo executable
To use the library from another CMake project:
find_package(shmem_writer REQUIRED)
target_link_libraries(my_app PRIVATE shmem_writer::shmem_writer)Built with uv. See destination/ directory for details.
When containers are killed (e.g., via docker compose down, SIGKILL, or a crash), the POSIX shared memory segment and semaphores may persist in the Docker VM's /dev/shm. Because the containers use ipc: host, these objects live in the host's (or Docker VM's) IPC namespace and survive container restarts. Stale semaphores with incorrect values will cause the system to deadlock on the next run.
To clean up stale IPC objects, run a temporary container with host IPC access:
docker run --rm --ipc=host ubuntu:22.04 \
rm -f /dev/shm/sem.haidis_sem /dev/shm/sem.haidis_sem_ack /dev/shm/haidis_shmemOn macOS, /dev/shm does not exist on the host filesystem — it only exists inside the Docker VM, so cleanup must be done from within a container as shown above.
Symptoms of stale IPC: Both containers start and initialize successfully, but no data is transferred (writer blocks on sem_wait, reader blocks on sem.acquire).
Shared memory configuration parameters are defined in shared/config.env.