2009-05-16 4 views
3

J'ai un code de sémaphore très basique qui fonctionne très bien sur Linux, mais qui ne peut pas fonctionner correctement sur OS X ... Il renvoie le résultat le plus étrange. ..SÉJ/sem_getvalue Behavior sémaphore sur OS X

#include <iostream> 
#include <fcntl.h> 
#include <stdio.h> 
#include <semaphore.h> 

int main() 
{ 
    sem_t* test; 
    test = sem_open("test", O_CREAT, 0, 1); 

    int value; 
    sem_getvalue(test, &value); 
    printf("Semaphore initialized to %d\n", value); 
} 

ce sur OS Compiler X avec g ++ retourne la sortie suivante:

iQudsi:Desktop mqudsi$ g++ test.cpp 
iQudsi:Desktop mqudsi$ ./a.out 
Semaphore initialized to -1881139893 

Alors que sur Ubuntu, je reçois le résultat nettement plus sain d'esprit-:

iQudsi: Desktop mqudsi$ g++ test.cpp -lrt 
iQudsi:Desktop mqudsi$ ./a.out 
Semaphore initialized to 1 

Je suis dans ce domaine depuis 3 heures d'affilée, et ne peut pas comprendre pourquoi OS X est de retour des résultats bizarres ...

J'ai essayé d'utiliser des chemins de fichiers comme le nom sémaphores, il n'a pas une différence.

J'apprécierais toute aide que je pourrais obtenir.

Répondre

6
$ g++ sem-testing.cc -Wall 
$ ./a.out 
sem_getvalue: Function not implemented 
$ man sem_getvalue 
No manual entry for sem_getvalue 

vous utilisez une fonction qui est actuellement mis en œuvre ne dans Mac OS X et l'entier que vous imprimez contient les données par défaut que l'entier a été initialisé avec qui était probablement des données aléatoires qui étaient encore en mémoire. Si vous l'aviez mis à zéro, en le réglant sur int value = 0;, vous auriez peut-être déjà détecté cette erreur plus tôt.

Ce code je (grâce à bdonlan):

#include <iostream> 
#include <fcntl.h> 
#include <stdio.h> 
#include <semaphore.h> 

int main() 
{ 
    sem_t* test; 
    test = sem_open("test", O_CREAT, 0, 1); 
    if (test == SEM_FAILED) { 
     perror("sem_open"); 
     return 1; 
    } 

    int value; 
    if (sem_getvalue(test, &value)) { 
     perror("sem_getvalue"); 
     return 1; 
    } 
    printf("Semaphore initialized to %d\n", value); 
} 
8

Testez-vous les erreurs? Essayez:

#include <iostream> 
#include <fcntl.h> 
#include <stdio.h> 
#include <semaphore.h> 

int main() 
{ 
    sem_t* test; 
    test = sem_open("test", O_CREAT, 0, 1); 
    if (test == SEM_FAILED) { 
     perror("sem_open"); 
     return 1; 
    } 

    int value; 
    if (sem_getvalue(test, &value)) { 
     perror("sem_getvalue"); 
     return 1; 
    } 
    printf("Semaphore initialized to %d\n", value); 
} 
+1

Le premier contrôle doit être « si (test == SEM_FAILED) » plutôt que le test, puisque c'est la valeur d'échec documenté (et en fait -1, pas 0). – smorgan

+0

J'ai posté un suivi qui contient la raison pour laquelle son code a échoué: http://stackoverflow.com/questions/871435/odd-incorrect-semaphore-behavior-on-os-x/871794#871794 –

2

Eh bien, peut-être sem_open() est un échec - vous ne l'avez pas tester. Ou, peut-être que OSX ne prend pas en charge les sems posix partagés - si/dev/shm n'est pas monté, le système ne supporte généralement pas sem_open().

Vous pouvez utiliser des sémaphores SysV.

Une question similaire concernant Slackware a été posée ici: how-do-i-stop-semopen-failing-with-enosys

Cependant, des recherches plus poussées montre OSX nommé semaphones sont construits sur le dessus de Mach sémaphores, et vous devez probablement les sem_unlink() lorsque vous avez terminé (non juste sem_close(), ou peut-être à la place), et vous devez être prudent sur les autorisations - Je suggère commençant par 0777 ou peut-être 0700, au lieu de 0. Voir posiz semaphores in Darwin