私は2つの異なるアプリケーションの間でPOSIXモデル内に共有動的配列を持っています。コピーせずにサイズを変更できるようにしたいと思います。残念ながら、私はC言語でPOSIX共有メモリを増減する適切な解決策を見つけることができませんでした。ウェブでは、説明が不十分で悲惨な例が多い多くの文書が見つかりました。私はいくつかの興味深いトピックを見つけることができましたが、それらのすべては、私には不向きである:POSIX共有メモリのサイズを変更します。動作例
"Linux System Programming" - "Mapping Files into Memory" Part: "Resizing a Mapping" - どこSHMのサイズを変更するには、no実施例ではありません。
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