Re: data structures on shared memory?
- From: Eric Sosman <eric.sosman@xxxxxxx>
- Date: Mon, 19 Dec 2005 13:15:44 -0500
Chinlu wrote On 12/19/05 12:36,:
> Hi,
>
> I've got a bit of a complex data structure based on linked lists, which
> I use for reading and storing contents of a config-file in memory.
>
> Now I need to port all of this towards to a shared-memory model. The
> point is that I've been trying to do something like that but haven't
> achieved it, though.
>
> As a example, let's say my structure handles data in this way:
> room->tables->knives, where you can have only one room, but any numer
> of tables as well as any no. of knives per table, which depends on the
> data stored in the file.
>
> As far as I can tell, I don't think I need to need to apply any
> producer-consumer model, as once set, further access to this data would
> be done read-only.
>
> I just need to handle properly a bit of recursion, but as soon as I try
> using pointers I get into troubles.
>
> Althought I can handle to have a void pointer whithin my structure and
> be properly assigned and passed to the shared memory segment, as soon
> as I try nesting it (which Is what I need), it runs off.
>
> I've been trying different ways of doing this, but no one seems to
> work.
>
> Can anyone tell me something about?
If the shared memory occupies the same set of virtual
addresses in all the processes that share it, then a pointer
value produced by one process is valid in all the others.
But if the shared memory is mapped starting at 0x80000000
in one process and in 0xC4000000 in another, pointer values
are process-specific and not interchangeable.
There are two principal ways to handle this difficulty.
First, you can try various tricks to see to it that the
shared memory is mapped identically in all processes. One
way to accomplish this is to map the shared memory in one
"ancestor" process before it fork()s all the others; they
will inherit the mapping and thus (obviously) use the same
virtual addresses. However, this won't work if fork() is
followed by exec(), because one of the first things exec()
does is discard the old address space. Another way is to
specify the same virtual address when each process attaches
to the shared memory (details vary depending on what kind of
shared memory you're using); the problem with this approach
is that the desired virtual address might not be available
so a process might not be able to attach in the desired way.
The second principal method is to give up on pointers
and use offsets instead. Let each process map the shared
memory at any convenient base address, even if the base
addresses in different processes are not the same. Then
link your data structures together with offsets, probably
expressed as size_t values. One global variable and a pair
of macros convert pointers to and from offsets:
unsigned char *SharedMemoryBase = ...;
#define OFF2PTR(off) (void*)(SharedMemoryBase + (off))
#define PTR2OFF(ptr) (size_t) \
((unsigned char*)(ptr) - SharedMemoryBase)
Yes, you lose a little: a pointer can carry information
about the pointed-to type, while an offset does not. This
means you need to exercise extra discipline to be sure you
don't mix-'n-match pointers to different types accidentally.
However, if you can't guarantee identical address mappings
in the various processes, some sacrifices are required.
--
Eric.Sosman@xxxxxxx
.
- Follow-Ups:
- Re: data structures on shared memory?
- From: Chinlu
- Re: data structures on shared memory?
- References:
- data structures on shared memory?
- From: Chinlu
- data structures on shared memory?
- Prev by Date: Re: How do you close a port immediately?
- Next by Date: Re: recv() - How do you know the length of buffer that you are going to receive?
- Previous by thread: data structures on shared memory?
- Next by thread: Re: data structures on shared memory?
- Index(es):
Relevant Pages
|