2011-11-17 39 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