zhangyin27 发表于 2009-3-16 17:09:28

求助ACE_MMAP_MEMORY_POOL内存池相关问题

内存池用的是
ACE_Malloc_T <ACE_MMAP_MEMORY_POOL,
      ACE_Process_Mutex,
      ACE_PI_Control_Block>

分配空间后用字符串进行绑定,但是当初始分配的内存用完之后,内存池会自动扩展,这时候对名字进行find操作就会出错,而且原来从内存池中分配的指针会由于内存池扩展时地址变动而变得无效
想知道有没有办法解决这个问题,或者让内存池不再扩展空间

winston 发表于 2009-3-16 17:46:48

记得ACE程序员指南上说过这个问题吧。

winston 发表于 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.

zhangyin27 发表于 2009-3-19 16:25:33

回复 #3 winston 的帖子

谢谢解答
但是好像说的不是一个问题

我描述的问题更像是这个
    /**
   * The base address will be selected by the OS for each call to mmap.
   * Caution should be used with this mode since a call that requires the
   * backing store to grow may change pointers that are cached by the
   * application.
   */
    NEVER_FIXED = 2
这是ACE源代码里面的注释 ace_wrappers\ace\mmap_memory_pool.h

我用的ACE_MMAP_Memory_Pool_Options options(0, ACE_MMAP_Memory_Pool_Options::ALWAYS_FIXED,1,(size_t)Default_Memory_Pool_Size);
会自动转成FIRSTCALL_FIXED,因为如果手动给定基地址的话不能保证可用,而且共享内存的几个进程会有的无法打开这个内存池
用这个options最后几个进程都能打开内存池,虽然基地址看起来不一样,但是运行时候的共享内存功能没有问题
但是如果内存池大小不够了,内存池扩大,程序里面已分配的指针就会指向不可用的地方,就是上面注释里面的 a call that requires the
   * backing store to grow may change pointers that are cached by the
   * application.
只是我没有使用NEVER_FIXED 这个选项啊


以下是我的测试代码

#include <ace/Time_Value.h>
#include <ace/OS_NS_stdlib.h>
#include <ace/OS_NS_stdio.h>
#include <ace/OS_NS_unistd.h>
#include <ace/Process_Mutex.h>
#include "ace/MMAP_Memory_Pool.h"
#include "ace/Hash_Map_With_Allocator_T.h"
#include "ace/Malloc_T.h"
#include "ace/PI_Malloc.h"
#include "ace/Process.h"
#define BACKING_STORE "map.store"
#define MAP_NAME "records.db"
typedef ACE_Allocator_Adapter<ACE_Malloc_T <ACE_MMAP_MEMORY_POOL,
ACE_Process_Mutex,
ACE_Control_Block>
> ALLOCATOR;
ACE_Process_Mutex coordMutex("Coord-Mutex");
int ACE_TMAIN (int argc, ACE_TCHAR *[])
{
ALLOCATOR * shmem_allocator = 0;
ACE_MMAP_Memory_Pool_Options options
(0,
ACE_MMAP_Memory_Pool_Options::ALWAYS_FIXED,1,(size_t)64*1024*1024);
ACE_NEW_RETURN (shmem_allocator,
ALLOCATOR (BACKING_STORE,
BACKING_STORE,
&options),
-1);
char*ptr=(char*)shmem_allocator->malloc(10*1024*1024);
strcpy(ptr," test ");
printf("%s",ptr);
char*pte=(char*)shmem_allocator->malloc(74*1024*1024);//分配后ptr失效
strcpy(pte," 1test1 ");
printf("%s",pte);
printf("%s",ptr);
return 0;
}

[ 本帖最后由 zhangyin27 于 2009-3-19 16:33 编辑 ]
页: [1]
查看完整版本: 求助ACE_MMAP_MEMORY_POOL内存池相关问题