2011-11-17 40 views
1

我有一个共享内存一个奇怪的问题。EEXIST上shmget的

方法shmget返回-1并且errno设置为EEXIST。据男子说,只有在提供标志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. 

还有一个问题:这是真的,那mode_flags(即0x660)是不是要当使用执行shmget?

回答

4

权限模式需要,不是十六进制指定。 0x660(十六进制)= 03140(八进制)。而IPC_EXCL标志有在Linux ABI八进制值02000 - 所以用0x660代替0660你不小心设置IPC_EXCL,这就是为什么你的错误。

如果我在你的程序改变0x660两个实例来0660和解决其他的东西,使之不能编译(值得注意的是,你离开了所有的报头和MAX_SIZE定义),它按预期工作。

+0

这是有史以来最尴尬的时刻。就像......曾经......甚至不知道该说覆盖我的耻辱是什么,我用八进制系统几乎天天要求...感谢您的帮助:) –

+2

@xavier - 论笨蛋错误一长串我们在生活中这个人甚至不会接近顶端。最好避免所有这些,只使用符号常量,例如S_IRUSR,S_IRGRP等等。它更便携,更少头痛。 – Duck

+0

@Duck我不知道这件事,我可以阅读和理解'0660'一个*比'S_IRUSR快很多* | S_IWUSR | S_IRGRP | S_IWGRP'。 – zwol