I am writing an interface to allow communication between a main program written in C and extension scripts written in python and run in a separate python interpreter process. The interface uses a UNIX socket for small amounts of data and POSIX shared memory for large arrays. The C program handles all creation, resource tracking and final unlinking of shared memory.
This works perfectly on Linux. I can transfer data between the two processes as expected using the shm.
However when exactly the same code runs on MacOS, although it runs without error the shared memory is always full of zeroes when read from the other process to the one that populated the memory. e.g. if I write image data into the shm from C, and read it from python, it's all zero. If I write image data into the shm from python and read it from C, again it's all zero. I create the shm in C as follows: (some error handling lines removed for clarity)
void *shm_ptr = NULL; snprintf(shm_name_ptr, 30, "/%08x%08x%08x%04x", my_random_int(), my_random_int(), my_random_int(), my_random_int()); debug_print("shm name: %s\n", shm_name_ptr); *fd = shm_open(shm_name_ptr, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); ftruncate(*fd, aligned_size) == -1); shm_ptr = mmap(NULL, (size_t) aligned_size, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0); *shm_ptr_ptr = shm_ptr; And then the details are passed to python through the socket. I haven't reproduced the details of that because the code is fairly long with #ifdefs for Windows etc., but the socket mechanism provably works and I can print the shm name as it is created in C and as it is received in python and show that they are the same:
shm name: /b6c31655f708d0e20760b60bc483 SHM allocation: Original size: 25941632, Aligned size: 25944064, Page size: 4096 Truncating shm file to 25941632 bytes log: b'/b6c31655f708d0e20760b60bc483' (The first lines of text are printed from C, the last is printed from python.)
The __init__ function from the wrapper class I'm using in python to open the shm is shown below:
class SharedMemoryWrapper: """ Wrapper class to handle shared memory creation and cleanup across platforms. """ def __init__(self, name: str, size: int): self.name = name self.size = size # Store intended size separately self._shm = None try: # First try to attach to existing shared memory self._shm = shared_memory.SharedMemory(name=self.name) unregister(self._shm._name, "shared_memory") except FileNotFoundError: # If it doesn't exist, create new shared memory print("Existing SHM not found, creating a new one...") self._shm = shared_memory.SharedMemory(name=self.name, create=True, size=self.size) (The unregister() call is there because the SHM is always allocated, tracked and cleaned up by the C program and passed to the python program, so this suppresses warning messages about shm leaks when the python script exits.)
Once the name and size are received over the socket the shared memory object is initialized using SharedMemoryWrapper(name=name_from_socket, size=size_from_socket)
On Linux the try block works and the shm is opened correctly, however on MacOS I see the message "Existing SHM not found, creating a new one..."
Please can someone explain what is different about MacOS here, and how can I fix it so that the existing shm is opened correctly?
SharedMemoryWrapperobject? Please try to create a minimal reproducible example to show us.shm_open()?