Linux C:访问共享内存失败并出现“无效参数”,即使它刚刚创建

Posted

技术标签:

【中文标题】Linux C:访问共享内存失败并出现“无效参数”,即使它刚刚创建【英文标题】:Linux C: Accessing shared memory fails with `Invalid Argument` even though it was just created 【发布时间】:2020-03-03 09:41:16 【问题描述】:

我的这个函数负责创建一个共享内存段。如您所见,我检查EEXIST 以防已存在与此密钥的共享内存。由于我定期使用相同的密钥执行程序,因此该共享内存在第一次程序执行后存在。

作为测试,之后我尝试通过shmat() 直接访问共享内存。但无论出于何种原因,它都失败了。这是控制台的输出:

Shared memory with Key 4661 already exists, continue...
Failed to obtain `Shared Memory`: Invalid argument

这是函数:

#define SHM_KEY 0x1235
int create_shrd_memory(uint64_t size) 
    const int shmid = shmget(SHM_KEY, size, IPC_CREAT | IPC_EXCL);
    if(shmid == -1) 
        if(errno == EEXIST) 
            printf("Shared memory with Key %d already exists, continue...\n", SHM_KEY);
            char *shdmem = shmat(SHM_KEY, NULL, 0);
            if(shdmem == -1) 
                fprintf(stderr, "Failed to obtain `Shared Memory`: %s\n", strerror(errno));
            
            shmdt(shdmem);
            return SHM_KEY;
         else 
            fprintf(stderr, "Failed to obtain Shared Memory: %s\n", strerror(errno));
            perror("shmget");
            exit(1);
        
    

    return shmid;

如果我忘记给shmdt()打电话,你知道会发生什么吗?这会导致这个错误吗?

【问题讨论】:

你为什么首先在 shmget 上使用 IPC_EXCL?看来您想要的正是在没有该标志的情况下调用时的行为。 【参考方案1】:

shmat第一个参数是shmget的返回值,你混合了key和id。

你的代码应该是这样的:

int create_shrd_memory(uint64_t size) 
    int shmid = shmget(SHM_KEY, size, IPC_CREAT | IPC_EXCL);
    if(shmid == -1) 
        if(errno == EEXIST) 
            printf("Shared memory with Key %d already exists, continue...\n", SHM_KEY);

            shmid = shmget(SHM_KEY, size, 0);

            char *shdmem = shmat(shmid, NULL, 0);
            if(shdmem == -1) 
                fprintf(stderr, "Failed to obtain `Shared Memory`: %s\n", strerror(errno));
            
            shmdt(shdmem);
            return SHM_KEY;
         else 
            fprintf(stderr, "Failed to obtain Shared Memory: %s\n", strerror(errno));
            perror("shmget");
            exit(1);
        
    

    return shmid;
 

【讨论】:

以上是关于Linux C:访问共享内存失败并出现“无效参数”,即使它刚刚创建的主要内容,如果未能解决你的问题,请参考以下文章

linux c编程:Posix共享内存区

Linux进程间通信——使用共享内存(转)

循环中的PostgreSQL DROP TABLE失败,出现ERROR:共享内存

win x64 下安装 oracle 12c 出现以下问题, [INS-30131] 执行安装程序验证所需的初始设置失败。

win x64 下安装 oracle 12c 出现以下问题, [INS-30131] 执行安装程序验证所需的初始设置失败。

Linux 进程间通信 --共享内存