Ich habe ein gemeinsames dynamisches Array im POSIX-Modell zwischen zwei verschiedenen Anwendungen. Ich möchte eine Fähigkeit haben, seine Größe zu ändern, ohne zu kopieren. Leider konnte ich keine richtige Lösung finden, um den gemeinsamen POSIX-Speicher in der C-Sprache zu erhöhen oder zu verringern. Im Internet habe ich viele Dokumente mit schlechten Erklärungen und elenden Beispielen gefunden. Ich habe es geschafft, einige interessante Themen zu finden, aber alle von ihnen sind nicht geeignet für mich:Größe ändern POSIX Shared Memory. Ein funktionierendes Beispiel
"Linux System Programming" - "Mapping Files into Memory" Part: "Resizing a Mapping" - wo ist kein Arbeitsbeispiel SHM zu ändern.
How do I implement dynamic shared memory resizing? - Nur eine Beschreibung. Habe kein Beispiel.
mremap function failed to allocate new memory - Lieblingsantwort funktioniert nicht.
c/linux - ftruncate and POSIX Shared Memory Segments - rszshm verwenden mremap() überhaupt nicht. Es kopiert stattdessen Speicher. Der schlimmste Weg.
Ich habe ein Beispiel entwickelt, wie ich die Dokumentation verstehe. Leider funktioniert es nicht richtig. Bitte geben Sie mir einen Hinweis, wo ich falsch liege. Und sei bitte so freundlich, mir ein funktionierendes Beispiel zu geben.
In der Dokumentation habe ich gefunden, dass ich ftruncate() vor mremap() verwenden muss, aber ich konnte nicht richtige Syntax für die Verwendung von ihnen finden. Außerdem arbeitet mremap() mit ausgerichteten Speicherseiten. Wie erhöht man in diesem Fall den gemeinsamen Speicher richtig?
/* main.c */
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <errno.h>
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;
}
Körperbau:
$ gcc -g -O0 -ggdb -pipe -Wall -Wextra -Wpedantic -Wshadow -march=native -std=c11 -o ./main ./main.c -lrt
Run:
$ ./main
Error on mremap(): Bad address
Zumindest müssen Sie Größen in Bezug auf die Seitengröße messen. siehe 'getpagesize()' oder 'sysconf()'. Und um den Speicher zwischen Prozessen zu teilen, müssen Sie eine Möglichkeit finden, die neue Größe den anderen Prozessen mitzuteilen. – joop