在shmget上没有IPC_EXCL的EEXIST

时间:2011-11-17 18:13:05

标签: linux shared-memory

我对共享内存有一个奇怪的问题。

方法shmget返回-1,errno设置为EEXIST。据man说,只有在提供了IPC_EXCLIPC_CREAT标志时才有可能。

我的代码:

int main()
{
        int shmid = shmget(0xABCD, MAX_SIZE, IPC_CREAT | 0x660);
        int shmid2 = shmget(0xABCD, MAX_SIZE, IPC_CREAT | 0x660 );
        if(shmid == -1)
        {
                if(errno == EEXIST)
                        perror("Error");
                return -1;
        }
        if(shmid2 == -1)
        {
                if(errno == EEXIST)
                        perror("Error2");
                return -1;
        }
        shmctl(shmid, IPC_RMID, NULL);
        return 0;
}

它使用-Wall编译而没有警告,我检查ipcs是否已经存在(并在需要时删除它)。输出为Error2: File exists。 当我将第二个shmget更改为:

时,它可以正常工作
int shmid2 = shmget(0xABCD, MAX_SIZE, 0 );

来自man shmget

EEXIST     IPC_CREAT | IPC_EXCL was specified and the segment exists. 

还有一个问题:是不是在尝试执行shmget时没有使用mode_flags(即0x660)?

1 个答案:

答案 0 :(得分:4)

权限模式需要在 octal 中指定,而不是十六进制。 0x660(十六进制)= 03140(八进制)。并且IPC_EXCL标志在Linux ABI中具有八进制值02000 - 因此使用0x660代替0660您会意外设置IPC_EXCL,这是为什么你得到错误。

如果我在程序中将0x660的两个实例都更改为0660并修复了其他使其无法编译的内容(特别是,您遗漏了{{1}的所有标题和定义})它按预期工作。