MacOS下C与Python跨进程POSIX共享内存读取全零的问题求助
我正在写一个接口,实现C语言主程序和Python扩展脚本之间的通信,Python脚本运行在独立的解释器进程中。这个接口用UNIX套接字传输小数据,用POSIX共享内存传输大数组。所有共享内存的创建、资源跟踪和最终的unlink操作都由C程序处理。
在Linux上这完全没问题,我可以通过共享内存在两个进程间正常传输数据。
但在MacOS上运行完全相同的代码时,虽然没有报错,但从写入进程的另一端读取共享内存时,里面全是零。比如从C写入图像数据到共享内存,Python读取时全是零;反过来从Python写入,C读取也全是零。
我在C中创建共享内存的代码如下(为了清晰去掉了部分错误处理代码):
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;
然后我通过套接字把共享内存的信息传给Python。这部分代码比较长还有Windows相关的#ifdef,所以就不贴了,但套接字机制是没问题的——我可以打印C中创建的共享内存名称,和Python接收到的名称,两者是一致的:
shm name: /b6c31655f708d0e20760b60bc483 SHM allocation: Original size: 25941632, Aligned size: 25944064, Page size: 4096 Truncating shm file to 25941632 bytes log: b'/b6c31655f708d0e20760b60bc483'
(前几行是C打印的,最后一行是Python打印的)
我在Python中用来打开共享内存的包装类的__init__函数如下:
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)
(unregister()调用是因为共享内存始终由C程序分配、跟踪和清理,然后传给Python程序,这样做是为了避免Python脚本退出时出现共享内存泄漏的警告)
当通过套接字接收到名称和大小后,我会用SharedMemoryWrapper(name=name_from_socket, size=size_from_socket)初始化共享内存对象。
在Linux上,try块能正常执行,共享内存被正确打开;但在MacOS上,我会看到“Existing SHM not found, creating a new one...”这条消息。
有没有人能解释一下MacOS在这里有什么不同?我该怎么修改才能让Python正确打开已有的共享内存?
备注:内容来源于stack exchange,提问作者Adrian K-B.

