2017-07-14 12 views
2

J'écris un programme en C où je distribue des cartes à n joueurs, représentés par n processus en fourche. Je souhaite pour eux de partager le même jeu de cartes, donc j'essaie d'utiliser mmap() pour garder la trace de la taille du pont, mais la machine pour laquelle je dois compiler ce programme ne permet pas MAP_ANONYMOUS ou MAP_ANON. Existe-t-il un autre moyen de stocker une variable globale dans la mémoire partagée qui serait toujours compatible C89/pré Linux 2.4?Mémoire partagée en C et MAP_ANONYMOUS manquant?

Mon programme pour le contexte:

static int *deck_size; 

int pop(int *arr, int *size, int loc) 
{ 
    int i; 
    int val = arr[loc]; 
    for(i = loc; i < (*size - 1); i++) 
    { 
     arr[i] = arr[(i+1)]; 
     arr[*size] = '\0'; 
    } 
    *size = *size-1; 
    return val; 
} 

int main(int argc, char* argv[]) 
{ 
    pid_t pid, wpid; 
    int status, index, players, rdm_card; 
    char outbuf[100]; 
    int deck[] = 
    {1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13}; 

    deck_size = mmap(NULL, sizeof *deck_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); 
    *deck_size = 52; 
    /* reject an execution with no arguments */ 
    if(argv[1] == NULL) 
    { 
     write(STDERR_FILENO, "Usage: dealer <n>\n", 18); 
     exit(EXIT_FAILURE); 
    } 
    else 
    { 
     if((players = atoi(argv[1])) < 1) 
     { 
      write(STDERR_FILENO, "n cannot be less than 1\n", 24); 
      exit(EXIT_FAILURE); 
     } 
    } 

    srand (time(NULL)); 

    rdm_card = rand() % *deck_size; 

    for(index = 0; index < players; index++) 
    { 
     pid = fork(); 
     if (pid == 0) { 
      sprintf(outbuf, "random card: %d\n", pop(deck, deck_size, rdm_card)); 
      write(STDOUT_FILENO, outbuf, 17); 
      printf("size of deck %d!\n", *deck_size); 
      exit(EXIT_SUCCESS); 
     } else if (pid < 0) { 
      write(STDERR_FILENO, "fork error\n", 11); 
      exit(EXIT_FAILURE); 
     } else { 
      do { 
       wpid = waitpid(pid, &status, WUNTRACED); 
      } while (!WIFEXITED(status) && !WIFSIGNALED(status)); 
     } 
    } 
    return 0; 
} 
+2

Avez-vous regardé 'man 2 shmget'? Il décrit l'ancienne interface de mémoire partagée System V qui était utilisée avant POSIX shm –

+2

Avez-vous pensé à définir '_BSD_SOURCE' ou' _SVID_SOURCE' pour obtenir MAP_ANONYMOUS de

+0

Y a-t-il une raison spécifique pour laquelle vous essayez d'utiliser des processus forkés ici? À moins que ce ne soit une exigence du projet (par exemple, pour une tâche de programmation), il vaut mieux utiliser des threads ... – duskwuff

Répondre

1

Lorsque vous lisez bien la page de manuel MMAP(2)-il clairement que MAP_ANONYMOUS est pris en charge depuis le noyau Linux 2.4.

L'utilisation de MAP_ANONYMOUS conjointement avec MAP_SHARED est pris en charge sur Linux que depuis le noyau 2.4.

Assurez-vous de définir _BSD_SOURCE ou _SVID_SOURCE pour obtenir MAP_ANONYMOUS

#define _BSD_SOURCE 
+0

Merci! Je n'avais pas réalisé que j'avais besoin de les définir. De plus, '#define _DEFAULT_SOURCE', est la version plus récente de' _BSD_SOURCE' et '_SVID_SOURCE'. – MSDOStoevsky

+0

@MSDOStoevsky - Il y a un tout nouveau trou de lapin à descendre pour ces macros :) J'utilise généralement '_X_OPEN_SOURCE' ou' _POSIX_SOURCE'. J'ai trouvé '_X_OPEN_SOURCE' ou' _POSIX_SOURCE' fonctionnent mieux avec les compilateurs C++ qui utilisent des bibliothèques C. Voir aussi [1.3.4 Macros de test de fonctionnalités] (https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html) dans le manuel GNU. Et Newlib est légèrement différent de Glibc. – jww

+0

Mais la question dit "pré Linux 2.4". Cela ne veut-il pas dire Linux 2.2 et plus tôt? –