How Do I Store and Retrieve a Struct into a Shared Memory Area in C
shmget
just reserves some amount of shared memory - like creating a fixed-size file on disk. The flags are a permission mask (like the mode
parameter for open
) in the low 9 bits plus some extra flags, IPC_CREAT
and IPC_EXCL
, corresponding to O_CREAT
and O_EXCL
for open
. To actually access that memory, you need to map it into the address space of your process ("attach" it - analogous to mmap
for files). This is done using shmat
(which returns a pointer). You then need to allocate your FILE
structures from that pointer. The whole process looks something like this:
int id;FILE_entry *entries;id = shmget(key, N * sizeof(FILE_entry), IPC_CREAT | 0644);entries = (FILE_entry *) shmat(id, NULL, 0);// you can now access entries as if it was a N-element array.// to turn it into a circular list, link the entries appropriately.
After mapping, you can work with it like regular memory - since it is regular memory. That's the whole point!
EDIT: One important caveat I forgot to mention. Putting a linked list into a shared memory segment like this will only work if all involved processes map it to the same address! So you either need to do that (using the second argument of shmat
) or switch from pointers to offsets relative to the base address of the shared memory range. That means turning your next
field from a pointer to a ptrdiff_t
and adding the base address of the mapped memory range whenever you load it (and subtracting it whenever you store it).
You call shmat(identifier, NULL, 0)
, getting back a pointer to the location the shared memory has been mapped to in your process. Either create your object(s) at that location, or memcpy
/memmove
them to that location.
You'll probably find Beej's Unix IPC guide useful, it contains a section specifically on shared memory.
After you get the key from shmget
, you have to use it to get the actual pointer via shmat
. Here is some sample:
int shmid;key_t key;FILE* shm;shmid = shmget(key, sizeof(FILE) * 10, IPC_CREAT | 0666);shm = shmat(shmid, NULL, 0);
This way, you will be able to access the shared memory using the shm
pointer. In this links you can see the manpage for shmget
and shmat
:
http://linux.die.net/man/2/shmget
http://linux.die.net/man/2/shmat
And see http://www.cplusplus.com for additional reference. It contains C reference also.
I don't know if I was clear enough, so, give some comments and I'll try to enlighten it for you, if necessary.
EDIT: In this site you can find a really simple example: http://simplestcodings.blogspot.com/2010/08/ipc-shared-memory-implementation-in-c.html