尝试在不丢失当前信息的情况下扩展共享内存区域
Trying to extend shared memory region without losing current info
我正在尝试创建一个共享内存段,它将保存一组初始数据,但需要在稍后的某个时间在另一个数据块可用时进行扩展。我在这里阅读了几篇文章并尝试了一些东西,但我似乎缺少一些魔法并且可以使用一些建议。
这里有一个测试程序可以说明我遇到的问题:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
#include <sys/mman.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
void *addr, *resaddr;
int *iarray;
int fd;
/* reserve a large address space - note that this doesn't ALLOCATE
* anything. It simply tells the OS to reserve this much space
* for us to eventually/potentially use. For this test case, we
* will ask for 1GByte of space. We include the MAP_NORESERVE
* flag to indicate that we don't want anything allocated, but
* people report that this flag is ignored as PROT_NONE is
* apparently sufficient for that purpose. */
fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0660);
addr = mmap(NULL, 1U << 30, PROT_NONE, MAP_ANONYMOUS | MAP_SHARED | MAP_NORESERVE, -1, 0);
fprintf(stderr, "GOT ADDRESS %p\n", addr);
iarray = (int*)addr;
/* now get resources for a piece of that file */
ftruncate(fd, 1U << 16);
resaddr = mmap(addr, 1U << 16, PROT_WRITE | PROT_READ, MAP_FIXED | MAP_SHARED, fd, 0);
fprintf(stderr, "RESERVED ADDRESS %p\n", resaddr);
/* put somthing into it */
iarray[1024] = 1;
fprintf(stderr, "iaddr[1024]: %d\n", iarray[1024]);
/* increase the size */
ftruncate(fd, 1U << 18);
fsync(fd);
resaddr = mmap(addr, (1U << 18) - (1U << 16), PROT_WRITE | PROT_READ, MAP_FIXED | MAP_SHARED, fd, 1U << 16);
fprintf(stderr, "EXTENDED RESERVED ADDRESS %p\n", resaddr);
/* add something to that region */
iarray[31000] = 2;
fprintf(stderr, "\tiarray[1024]: %d\n\tiarray[31000]: %d\n", iarray[1024], iarray[31000]);
exit(0);
}
运行 这会产生以下结果:
GOT ADDRESS 0x111396000
RESERVED ADDRESS 0x111396000
iaddr[1024]: 1
EXTENDED RESERVED ADDRESS 0x111396000
iarray[1024]: 0
iarray[31000]: 2
一切如我所料,唯一需要注意的是初始存储数据丢失(显然重置为零)。有没有人建议我应该采取哪些不同的方式来保留初始存储的数据?
据我了解,mmap()
的第三次调用不正确。
resaddr = mmap(addr, (1U << 18) - (1U << 16), PROT_WRITE | PROT_READ, MAP_FIXED | MAP_SHARED, fd, 1U << 16);
应替换为
resaddr = mmap(addr + (1U << 16), (1U << 18) - (1U << 16), PROT_WRITE | PROT_READ, MAP_FIXED | MAP_SHARED, fd, 1U << 16);
(offset参数是文件中的偏移量,不是内存中的)
我正在尝试创建一个共享内存段,它将保存一组初始数据,但需要在稍后的某个时间在另一个数据块可用时进行扩展。我在这里阅读了几篇文章并尝试了一些东西,但我似乎缺少一些魔法并且可以使用一些建议。
这里有一个测试程序可以说明我遇到的问题:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
#include <sys/mman.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
void *addr, *resaddr;
int *iarray;
int fd;
/* reserve a large address space - note that this doesn't ALLOCATE
* anything. It simply tells the OS to reserve this much space
* for us to eventually/potentially use. For this test case, we
* will ask for 1GByte of space. We include the MAP_NORESERVE
* flag to indicate that we don't want anything allocated, but
* people report that this flag is ignored as PROT_NONE is
* apparently sufficient for that purpose. */
fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0660);
addr = mmap(NULL, 1U << 30, PROT_NONE, MAP_ANONYMOUS | MAP_SHARED | MAP_NORESERVE, -1, 0);
fprintf(stderr, "GOT ADDRESS %p\n", addr);
iarray = (int*)addr;
/* now get resources for a piece of that file */
ftruncate(fd, 1U << 16);
resaddr = mmap(addr, 1U << 16, PROT_WRITE | PROT_READ, MAP_FIXED | MAP_SHARED, fd, 0);
fprintf(stderr, "RESERVED ADDRESS %p\n", resaddr);
/* put somthing into it */
iarray[1024] = 1;
fprintf(stderr, "iaddr[1024]: %d\n", iarray[1024]);
/* increase the size */
ftruncate(fd, 1U << 18);
fsync(fd);
resaddr = mmap(addr, (1U << 18) - (1U << 16), PROT_WRITE | PROT_READ, MAP_FIXED | MAP_SHARED, fd, 1U << 16);
fprintf(stderr, "EXTENDED RESERVED ADDRESS %p\n", resaddr);
/* add something to that region */
iarray[31000] = 2;
fprintf(stderr, "\tiarray[1024]: %d\n\tiarray[31000]: %d\n", iarray[1024], iarray[31000]);
exit(0);
}
运行 这会产生以下结果:
GOT ADDRESS 0x111396000
RESERVED ADDRESS 0x111396000
iaddr[1024]: 1
EXTENDED RESERVED ADDRESS 0x111396000
iarray[1024]: 0
iarray[31000]: 2
一切如我所料,唯一需要注意的是初始存储数据丢失(显然重置为零)。有没有人建议我应该采取哪些不同的方式来保留初始存储的数据?
据我了解,mmap()
的第三次调用不正确。
resaddr = mmap(addr, (1U << 18) - (1U << 16), PROT_WRITE | PROT_READ, MAP_FIXED | MAP_SHARED, fd, 1U << 16);
应替换为
resaddr = mmap(addr + (1U << 16), (1U << 18) - (1U << 16), PROT_WRITE | PROT_READ, MAP_FIXED | MAP_SHARED, fd, 1U << 16);
(offset参数是文件中的偏移量,不是内存中的)