Redimensionnez la mémoire partagée POSIX. Un exemple de travail

J’ai un tableau dynamic partagé dans le modèle POSIX entre deux applications différentes. Je voudrais pouvoir modifier sa taille sans copier. Malheureusement, je n’ai pas trouvé la bonne solution pour augmenter et diminuer la mémoire partagée POSIX en langage C. Sur le web, j’ai trouvé beaucoup de documents avec des explications médiocres et des exemples misérables. J’ai réussi à trouver des sujets intéressants, mais ils ne me conviennent pas tous:

  1. “Linux System Programming” – “Mapper des fichiers en mémoire” Partie: “Redimensionner un mappage” – où aucun exemple de travail ne permet de redimensionner SHM.

  2. Comment mettre en œuvre le redimensionnement dynamic de la mémoire partagée? – Une description uniquement. N’a pas d’exemple.

  3. La fonction mremap n’a pas réussi à atsortingbuer une nouvelle mémoire – La réponse préférée fonctionne mal.

  4. Redimensionnement rapide d’un fichier mmap

  5. Caractéristiques de la fonction mremap sous Linux

  6. La fonction mremap n’a pas pu allouer de nouvelle mémoire

  7. c / linux-ftruncate et POSIX Shared Memory Segments – rszshm n’utilise pas mremap () du tout. Il copie la mémoire à la place. La pire des manières

J’ai développé un exemple si je comprends la documentation. Malheureusement, cela ne fonctionne pas bien. S’il vous plaît donnez-moi un conseil, où je me trompe. Et s’il vous plaît soyez assez aimable pour me donner un exemple de travail.

Dans la documentation, j’ai trouvé que je devais utiliser ftruncate () avant mremap (), mais je n’ai pas trouvé de syntaxe correcte pour les utiliser. En outre, mremap () fonctionne avec les pages de mémoire alignées. Comment augmenter correctement la mémoire partagée dans ce cas?

/* main.c */ #define _GNU_SOURCE #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  int main(void) { size_t size_of_mem = 1024; int fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRWXO | S_IRUSR | S_IWUSR); if (fd == -1) { perror("Error in shm_open"); return EXIT_FAILURE; } if (ftruncate(fd, size_of_mem) == -1) { perror("Error in ftruncate"); return EXIT_FAILURE; } void *shm_address = mmap(0, size_of_mem, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, fd, 0); if (shm_address == MAP_FAILED) { perror("Error mmapping the file"); return EXIT_FAILURE; } /* Increase shard memory */ for (size_t i=0; i<1024; ++i){ /* Does 8 align memory page? */ size_t new_size_of_mem = 1024+(8*i); if (ftruncate(fd, new_size_of_mem) == -1) { perror("Error in ftruncate"); return EXIT_FAILURE; } /* mremap() works with aligned memory pages. How to properly increase shared memory in this case? */ void *temp = mremap(shm_address, size_of_mem, new_size_of_mem, MREMAP_MAYMOVE); if(temp == (void*)-1) { perror("Error on mremap()"); return EXIT_FAILURE; } size_of_mem = new_size_of_mem; } return 0; } 

Construire:

 $ gcc -g -O0 -ggdb -pipe -Wall -Wextra -Wpedantic -Wshadow -march=native -std=c11 -o ./main ./main.c -lrt 

Courir:

 $ ./main Error on mremap(): Bad address 

Vous perdez l’adresse de la nouvelle mémoire allouée / remappée affectée à temp .

Cela signifie que, depuis le deuxième cycle de for loop, vous déplacez une mémoire déjà déplacée.

Après la vérification de la valeur retournée par mremap, vous pouvez redirect la nouvelle adresse vers le pointeur shm_address .

 void *temp = mremap(shm_address, size_of_mem, new_size_of_mem, MREMAP_MAYMOVE); if(temp == (void*)-1) { perror("Error on mremap()"); return EXIT_FAILURE; } shm_address = temp;