I have a C++ application that allocates shared memory on a Linux system via shmget(2). The data that I store in the shared memory grows periodically, and I\'d like to resize th
It seems to me that the function mremap was implemented to perform what you want. You just have to precise in argument the old size and the new one of the shared memory segment. And if you add the flag MREMAP_MAYMOV, it allows to move the shared memory segment if needed (i.e if not enough free space just after the old shared memory segment).
Look at the manpage : http://man7.org/linux/man-pages/man2/mremap.2.html.
It seems for me that you can write your own memory manager for your purpose. The conception is quite simple:
N
bytes;2*N
size;I'm afraid we have nothing more to do with that. This is how std::vector
is implemented. And void *realloc()
in most of cases will return you the pointer to the new block of memory (but not to the extended old block).
Simple answer: there is no easy way.
The reasons are pretty logical. Shared memory is being attached to virtual space of every process individually. Each process has it's own virtuall address space. Each process is free to attach the segment at any (not literally, alignment sets some restrictions) arbitrary address. How can system guarantee that, let's say by extending area by 4MiB, every 'user' of this segment will be able to fit bigget block at the same starting address where the smaller segment previously was?
But you should not give up! You can be creative. You can come up with the idea of having one header segment, where you store information about real payload segment. You can make every process to obey some rules as for example: reattach payload segment when its id, as described somewhere in header segment, does not match the known one.
The advice: I suspect you know this, but never keep pointers to data within shared region, only offset.
I hope you'll have some use of my gibberish.