Question

Je suis en train de savoir comment remappez fichiers mappés en mémoire sur un Mac (quand je veux élargir l'espace disponible).

Je vois nos amis dans le monde Linux ont mremap, mais je ne trouve pas cette fonction dans les en-têtes sur mon Mac. /Developer/SDKs/MacOSX10.6.sdk/usr/include/sys/mman.h a ce qui suit:

  • mmap
  • mprotect
  • msync
  • munlock
  • munmap
  • mais pas mremap

man mremap confirme mes craintes.

J'ai actuellement munmap et mmmap si je veux redimensionner la taille du fichier mis en correspondance, ce qui implique toutes les pages invalidant chargées. Il doit y avoir une meilleure façon. Sûrement?

Je suis en train de écrire du code qui fonctionne sur Mac OS X et Linux. Je pourrais se contenter d'une macro à utiliser la meilleure fonction dans chaque cas si je HAD mais je préfère le faire correctement.

Était-ce utile?

La solution

Vous pouvez ftruncate le fichier à une grande taille (créant un trou) et mmapper tout cela. Si le fichier est persistant, je recommande de remplir le trou avec des appels d'écriture plutôt que par écrit dans la cartographie, sinon les blocs du fichier peuvent se inutilement fragmenté sur le disque.

Autres conseils

Si vous devez réduire la carte, juste munmap la partie à la fin que vous souhaitez supprimer.

Si vous avez besoin pour agrandir la carte, vous pouvez mmap le bon décalage avec MAP_FIXED aux adresses juste au-dessus de la vieille carte, mais vous devez faire attention que vous ne mappez pas sur quelque chose d'autre qui est déjà là. ..

Le texte ci-dessus est une sous strikeout mauvaise idée; MAP_FIXED est fondamentalement erroné, sauf si vous savez déjà ce qui est à l'adresse cible et que vous voulez remplacer atomiquement il. Si vous essayez de mapper quelque chose de nouveau si opportuniste la plage d'adresses est gratuite, vous devez utiliser mmap avec une adresse demandée, mais sans MAP_FIXED et voir si elle réussit et vous donne l'adresse demandée; si elle réussit, mais avec une adresse différente, vous aurez envie de unmap le nouveau mappage que vous venez de créer et d'assumer que l'allocation à l'adresse demandée n'a pas été possible.

Si vous développez en assez gros morceaux (disons, 64 Mo, mais cela dépend de la rapidité avec laquelle il pousse), le coût de vicier l'ancienne carte est négligeable. Comme toujours, de référence avant de prendre un problème.

Je n'ai aucune expérience avec la cartographie de la mémoire, mais il semble que vous pouvez mapper temporairement le même fichier deux fois un moyen d'élargir la cartographie sans perdre quoi que ce soit.

int main() {
    int fd;
    char *fp, *fp2, *pen;

      /* create 1K file */
    fd = open( "mmap_data.txt", O_RDWR | O_CREAT, 0777 );
    lseek( fd, 1000, SEEK_SET );
    write( fd, "a", 1 );

      /* map and populate it */
    fp = mmap( NULL, 1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
    pen = memset( fp, 'x', 1000 );

      /* expand to 8K and establish overlapping mapping */
    lseek( fd, 8000, SEEK_SET );
    write( fd, "b", 1 );
    fp2 = mmap( NULL, 7000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );

      /* demonstrate that mappings alias */
    *fp = 'z';
    printf( "%c ", *fp2 );

      /* eliminate first mapping */
    munmap( fp, 1000 );

      /* populate second mapping */
    pen = memset( fp2+10, 'y', 7000 );

      /* wrap up */
    munmap( fp2, 7000 );
    close( fd );
    printf( "%d\n", errno );
}

La sortie est zxxxxxxxxxyyyyyy.....

Je suppose que, si vous livre sur ce sujet, il peut être possible de manquer d'espace d'adressage plus rapide qu'avec mremap. Mais rien ne garantit de toute façon et il pourrait d'autre part être tout aussi sûr.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top