You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python创建共享内存后C++读取报错:无效参数 求排查方案

解决Python写入共享内存后C++读取失败的问题

问题原因

你遇到的错误是因为Python代码直接操作/dev/shm目录下的普通文件,而C++代码误用了shm_open函数——这个函数专门用于POSIX共享内存对象,它的参数不能带完整路径(比如/dev/shm/my_shared_memory),必须是不带路径的名称(如my_shared_memory),否则会返回"Invalid argument"错误。

另外还有潜在问题:Python写入的字符串没有添加空终止符\0,C++用std::string(static_cast<char*>(addr))构造时会读到内存中的随机空字符,导致内容包含垃圾数据。

解决方案

两种可行方案任选其一:

方案1:修改C++代码,直接打开/dev/shm下的文件(与Python逻辑一致)

把C++中的shm_open替换为标准open函数,直接读取Python创建的文件:

#include <iostream>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <cerrno> 
#include <cstring>

int main() {
    // 用open直接打开/dev/shm下的文件
    int shm_fd = open("/dev/shm/my_shared_memory", O_RDONLY);
    if (shm_fd == -1) {
        perror("Error opening shared memory file");
        return 1;
    }

    void* addr = mmap(NULL, 4096, PROT_READ, MAP_SHARED, shm_fd, 0);
    if (addr == MAP_FAILED) {
        std::cerr << "Error mapping shared memory" << std::endl;
        return 1;
    }

    // 读取到第一个空字符为止,避免垃圾数据
    std::string message(static_cast<char*>(addr), strlen(static_cast<char*>(addr)));

    std::cout << "Received message from Python: " << message << std::endl;

    if (munmap(addr, 4096) == -1) {
        std::cerr << "Error unmapping shared memory" << std::endl;
        return 1;
    }

    if (close(shm_fd) == -1) {
        std::cerr << "Error closing shared memory file" << std::endl;
        return 1;
    }

    return 0;
}

方案2:修改Python代码,使用POSIX共享内存对象(与C++的shm_open对应)

遵循POSIX共享内存标准用法,Python使用posix_ipc模块(需先安装:pip install posix-ipc):

修改后的write_data.py

import posix_ipc
import mmap

# 创建POSIX共享内存对象,名称不带/dev/shm路径
shm = posix_ipc.SharedMemory("/my_shared_memory", posix_ipc.O_CREAT | posix_ipc.O_RDWR, size=4096, mode=0o666)
mmap_obj = mmap.mmap(shm.fd, shm.size)

# 写入带空终止符的字符串,方便C++读取
message = "This is sample data"
mmap_obj.write((message + '\0').encode())

# 关闭资源
mmap_obj.close()
shm.close_fd()

修改后的read_shared_memory.cpp

#include <iostream>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <cerrno> 

int main() {
    // shm_open的名称只需带前导/,无需/dev/shm路径
    int shm_fd = shm_open("/my_shared_memory", O_RDONLY, 0);
    if (shm_fd == -1) {
        perror("Error opening shared memory");
        return 1;
    }

    // 获取共享内存实际大小(也可以硬编码4096)
    off_t shm_size = lseek(shm_fd, 0, SEEK_END);
    lseek(shm_fd, 0, SEEK_SET);

    void* addr = mmap(NULL, shm_size, PROT_READ, MAP_SHARED, shm_fd, 0);
    if (addr == MAP_FAILED) {
        std::cerr << "Error mapping shared memory" << std::endl;
        return 1;
    }

    std::string message(static_cast<char*>(addr));
    std::cout << "Received message from Python: " << message << std::endl;

    if (munmap(addr, shm_size) == -1) {
        std::cerr << "Error unmapping shared memory" << std::endl;
        return 1;
    }

    if (close(shm_fd) == -1) {
        std::cerr << "Error closing shared memory" << std::endl;
        return 1;
    }

    // 可选:不再需要时删除共享内存对象
    // shm_unlink("/my_shared_memory");

    return 0;
}

额外注意事项

  • 编译C++代码时需链接rt库:g++ read_shared_memory.cpp -o read_shared_memory -lrt
  • 确保Python和C++运行在同一用户权限下,避免权限错误
  • 共享内存数据不会自动清空,下次写入前需手动清理或覆盖

内容的提问来源于stack exchange,提问作者sheel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 20:35:57