|
发表于 2009-3-16 17:47:09
|
显示全部楼层
17.4 ACE_Malloc for ContainersAs you know, you can specify special-purpose allocators for containers. The container then uses the allocator to satisfy its memory needs. Wouldn't it be nice if we could use an ACE_Malloc shared memory allocator with the container and allocate containers in shared memory? This would mean that the container would allocate memory for itself in shared memory. The problem, of course, is that the allocator needs to implement the ACE_Allocator interface, but ACE_Malloc doesn't.
No need to fret, though, because ACE includes a special adapter class for this purpose. ACE_Allocator_Adapter adapts an ACE_Malloc-based class to the ACE_Allocator interface. This class template is very easy to use. To create the adapter, simply pass in the appropriate ACE_Malloc type. For example:
typedef ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex> MALLOC;typedef ACE_Allocator_Adapter<MALLOC> ALLOCATOR;Besides the issue of interface compatibility, another issue crops up. Most of the container classes keep a reference to the allocator they use and use this reference for all memory operations. This reference will point to heap memory, where the shared memory allocator itself is allocated. Of course, this pointer is valid only in the original process that created the allocator and not any other processes that wish to share the container. To overcome this problem, you must provide the container with a valid memory allocator reference for all its operations. As an example, ACE overloads the ACE_Hash_Map container—the new class is ACE_Hash_Map_With_Allocator—to provide this, and you can easily extend the idea to any other containers you wish to use.
Table 17.3. ACE_MMAP_Memory_Pool_Options AttributesOption Name
Description
base_address
Specifies a starting address for where the file is mapped into the process's memory space.
use_fixed_addr
Specifies when the base address can be fixed; must be one of three constants:
- FIRSTCALL_FIXED: Use the specified base address on the initial acquire
- ALWAYS_FIXED: Always use the specified base address
- NEVER_FIXED: Always allow the OS to specify the base address
write_each_page
Write each page to disk when growing the map.
minimum_bytes
Initial allocation size.
flags
Any special flags that need to be used for mmap().
guess_on_fault
When a fault occurs try to guess the faulting address and remap/extend the mapped file to cover it.
sa
LPSECURITY_ATTRIBUTES on Windows.
file_mode
File access mode to use when creating the backing file.
Finally, as most, if not all, ACE containers contain raw pointers, you cannot expect to use them between processes that map them to different base addresses. ACE does not include any container class that uses the position-independent pointers we showed you earlier, although you could easily create one on your own. Therefore, if you are going to use a container in shared memory, you must make sure that you can map the entire container into all sharing processes at the same base address. |
|