두 개의 서로 다른 응용 프로그램 사이에 POSIX 모델 내에서 공유 동적 배열이 있습니다. 복사하지 않고 크기를 변경할 수있는 기능을 원합니다. 불행히도 나는 C 언어로 POSIX 공유 메모리를 늘리거나 줄이기위한 올바른 해결책을 찾지 못했습니다. 웹에서 나는 가난한 설명과 비참한 예를 가진 많은 문서를 발견했다. 나는 몇 가지 흥미로운 주제를 찾으려면 관리했지만, 그들 모두가 나에게 적합하지 않은 : POSIX 공유 메모리 크기를 조정하십시오. 작업 예제
"Linux System Programming" - "Mapping Files into Memory" Part: "Resizing a Mapping"
- SHM의 크기를 조정 할 일 예는없는 곳.How do I implement dynamic shared memory resizing? - 설명 만. 예를 들어 보지 마십시오.
mremap function failed to allocate new memory - 좋아하는 답변이 잘못되었습니다.
- Fast resize of a mmap file
- - rszshm 전혀 mremap는()를 사용하지 않습니다. 대신 메모리를 복사합니다. 최악의 방법.
설명서를 이해하면서 예제를 개발했습니다. 불행히도 그것은 올바르게 작동하지 않습니다. 내가 잘못한 조언을 해주세요. 그리고 제게 실용적인 예를 들어 주시길 바랍니다.
설명서에서 mremap() 전에 ftruncate()를 사용해야한다는 것을 발견했지만이를 사용하기위한 올바른 구문을 찾을 수 없습니다. 게다가 mremap()은 정렬 된 메모리 페이지와 함께 작동합니다. 이 경우 공유 메모리를 올바르게 늘리는 방법은 무엇입니까?
/* 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;
}
빌드 :
$ gcc -g -O0 -ggdb -pipe -Wall -Wextra -Wpedantic -Wshadow -march=native -std=c11 -o ./main ./main.c -lrt
실행 :
$ ./main
Error on mremap(): Bad address
적어도 페이지 크기 측면에서 크기를 측정해야합니다. 'getpagesize()'또는'sysconf()'를 참조하십시오. 또한 프로세스간에 메모리를 공유하려면 새 크기를 다른 프로세스와 통신하는 방법을 찾아야합니다. – joop