2011-11-17 2 views
1

J'ai un problème étrange avec la mémoire partagée. La méthode shmget renvoie -1 et errno est définie sur EEXIST. Selon l'homme, cela n'est possible que lorsque les deux indicateurs IPC_EXCL et IPC_CREAT sont fournis.EEXIST sans IPC_EXCL sur shmget

Mon code:

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; 
} 

Il compile avec -Wall sans avertissement préalable, je vérifie avec IPCS si le segment est déjà présent (et l'enlever si nécessaire). La sortie est Error2: File exists. Il fonctionne quand je change la deuxième shmget à:

int shmid2 = shmget(0xABCD, MAX_SIZE, 0); 

Citation de man shmget:

EEXIST  IPC_CREAT | IPC_EXCL was specified and the segment exists. 

Et une autre question: est-il vrai que mode_flags (c.-à-0x660) ne sont pas utilisés en essayant de exécuter shmget?

Répondre

4

Les modes d'autorisation doivent être spécifiés en octal, pas en hexadécimal. 0x660 (hex) = 03140 (octal). Et le drapeau IPC_EXCL a la valeur octale 02000 dans l'ABI Linux - donc en utilisant 0x660 au lieu de 0660 vous êtes accidentellement la définition IPC_EXCL, ce qui explique pourquoi vous obtenez l'erreur.

Si je change les deux cas de 0x660 à 0660 dans votre programme et corriger les autres choses qui rendent compile pas (notamment, vous avez quitté tous les en-têtes et la définition de MAX_SIZE) fonctionne comme prévu.

+0

C'est le moment le plus embarrassant qui soit. Comme ... Jamais ... Je ne sais même pas quoi dire pour couvrir ma honte, j'utilise l'octal dans les appels système presque tous les jours ... Merci pour l'aide :) –

+2

@xavier - Sur la longue liste des erreurs de bonehead nous faire dans la vie celui-ci ne sera même pas proche du sommet. Mieux vaut éviter tout cela et utiliser simplement les constantes symboliques, par ex. S_IRUSR, S_IRGRP et ainsi de suite. C'est plus portable et moins de maux de tête. – Duck

+0

@Duck Je ne sais pas à ce sujet, je peux lire et comprendre '0660' a * beaucoup * plus vite que' S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP'. – zwol

Questions connexes