Linux伊甸园论坛's Archiver

zengjin8310 发表于 2006-1-5 20:24

想把STL中set放到LINUX的共享内存里, 不知道怎么办

想把STL中set放到LINUX的共享内存里, 不知道怎么办

如果能把STL的带动态内存分配的一些数据结构可以方便的放到共享内存, 哪电信银行等等系统的效率将会因为试用C++而提高很大效率

dearvoid 发表于 2006-1-5 20:46

放到 shared memory 里面就不是动态分配了,不过可以考虑自己写一套内存管理的函数来用

zengjin8310 发表于 2006-1-5 20:53

对啊, 我只是对这个Set的处理放在共享内存, 肯定要重载set的一堆函数, 但是觉得自己肯定重载出很多问题, 所以问一下有没有人有这样的使用经验?
我觉得ACE开发小组可以把这个功能添上, 这很有用

zengjin8310 发表于 2006-1-5 20:59

要是new有两种分配方式就好了
   new (Object);
   new( Object, shmid, beginshmaddr );
   这个自己可以写, 但是set中的new不是自己能控制的,
   如果ace改造STL set 加两个参数 set<T, shmid, beginshmaddr >就好了, 或者干脆来个
   class functor{
           virtual ... new( Object, shmid, beginshmaddr )=0;
   }
(不好意思, 两年没做过C++了, 不知道怎么重载new了, 大概这个样子吧)
   设计set<T, functor s>
   
   而使用者只需要继承funtor实现自己的newfuctor然后
   newfuntor myfunctor;
   set< string, myfunctor>这样调用
(同样也不好意思, 不知道模板怎么传functor了, 大概这个样子吧, 如果不行可以从构造函数传进functor)

DarkSpy 发表于 2006-1-6 08:58

shm 和 普通 mem 都一样,  kernel 有分配次数限制, 必须自己写内存池.
第二,写完内存池,重载 new, 如果不知道 placement new, 自己去看书,  语法结构
new (buf) obj
重载语法: void* operator new(size_t, buf_to_alloc);

这两点明白之后, 便可以修改 STL 的 allocator, 然后就可以让 set 进入共享内存了.

另: 不要忘记线程安全.

flag 发表于 2006-1-6 09:35

kernel 有分配次数限制......
没看到过啊,能说些细节吗?不过似乎也不知道细节能说些什么……

zengjin8310 发表于 2006-1-6 11:21

讲一下应用背景吧, 一个对性能要求极高的系统, 好多进程之间需要共享一块数据区, 因此想到了用共享内存, 然后这块数据区需要满足一个数据结构。

对于DarkSpy所说的allocator我查了一下STL set的源代码, 的却有这个参数,没用过, 要不咱们搞个出来?
不过偶n久没碰过C++了, 忘了不少~
我觉得这个还是很有用的如果电信,银行等等用C++写的话, 能实现这个非常重要。
线程安全暂时可以不用考虑, 如果这么设计一般都是只读的, 如果多进程同时更改一般把这些并发设计给数据库处理

flag 发表于 2006-1-6 11:55

说到应用,我是觉得一般电信和银行的服务都会采用小型机数据库,而不会去搞些共享内存的看上去很美的东西。

zengjin8310 发表于 2006-1-6 12:38

你的这个方案我建议过,曾经建议用mysql, 可是企要*鑫侍庖欢ㄒ?衅笠到饩觯?所以还是用db2 or Oracle而这两个数据库查询性能太低, 远不能满足要求, 做过测试, 如果在共享内存用线性的结构用简单的二分查找性能也比数据库好。 一天上亿笔, 十几分钟内每条数据做n种处理, 查n个表, 这样太低

zengjin8310 发表于 2006-1-6 12:41

用mysql5的话我做过测试, 基本可以满足查询性能, 但是, 很不幸, 不能用(原因很简单, 对于金融行业, 不再说)。所以只能共享内存

zengjin8310 发表于 2006-1-6 13:12

呼唤牛人~~

zengjin8310 发表于 2006-1-6 14:54

一个摘自C++STL的代码
15.4 A User-Defined Allocator
Writing your own allocator is not very hard. The most important issue is how you allocate or
deallocate the storage. The rest is more or less obvious. As an example, let's look at a naive
implementation of the default allocator:
//util/defalloc.hpp



namespace std {
     template <class T>
     class allocator
     {
     public:
//type definitions
         typedef size_t size_type;
         typedef ptrdiff_t difference_type;
         typedef T* pointer;
         typedef const T* const_pointer;
         typedef T& reference;
         typedef const T& const_reference;
         typedef T value_type;
//rebind allocator to type U
         template <class U>
         struct rebind
         {
             typedef allocator<U> other;
         };
//return address of values
         pointer address (reference value) const
         {
             return (&value);
         }
         const_pointer address (const_reference value) const
         {
             return (&value);
         }
/*constructors and destructor
*-nothing to do because the allocator has no state
*/
         allocator() throw()
         {
         }
         allocator(const allocator&) throw()
         {
         }
         template <class U>
         allocator (const allocator<U>&) throw()
         {
         }
         ~allocator() throw()
         {
         }
//return maximum number of elements that can be allocated
         size_type max_size () const throw()
         {
//for numeric_limits see Section 4.3, page 59
             return (numeric_limits<size_t>::max() / sizeof(T));
         }
//allocate but don't initialize num elements of type T
         pointer allocate (size_type num,
                           allocator<void>::const_pointer hint = 0)
         {
//allocate memory with global new
             return(pointer) (:perator new(num*sizeof(T)));
         }
//initialize elements of allocated storage p with value value
         void construct (pointer p, const T& value)
         {
//initialize memory with placement new
             new((void*)p)T(value);
         }
//destroy elements of initialized storage p
         void destroy (pointer p)
         {
// destroy objects by calling their destructor
             p->~T();
         }
//deallocate storage p of deleted elements
         void deallocate (pointer p, size_type num)
         {
//deallocate memory with global delete
             :perator delete((void*)p));
         }
     };
//return that all specializations of this allocator are
     interchangeable
     template <class T1, class T2>
     bool operator== (const allocator<T1>&,
                      const allocator<T2>&) throw()
     {
         return (true);
     }
     template <class T1, class T2>
     bool operator!= (const allocator<T1>&,
                      const allocator<T2>&) throw()
     {
         return (false);
     }
}

zengjin8310 发表于 2006-1-9 11:22

搞定! 看了一下allocator的默认实现,回忆了一下C++才发现, 写一个SHM 的allocator是多么容易的事!

DarkSpy 发表于 2006-1-9 17:26

kernel 有分配次数限制......
没看到过啊,能说些细节吗?不过似乎也不知道细节能说些什么……
-------------------------
我曾经做过这样的项目,是一个交易平台,我做的是 SHM, 用户要求将数据在 SHM 里交换, 我写SHM那块和接口, 而且还要求给接口客户端程序员能将 struct 的数据放入我的接口内, 能映射一份 struct, 在编译时期搞定, 写了 2 个星期, 用了 LOKI 的 bt 技术, 后来由于公司的人都不熟 template, 所以项目失败了, 不过经验也得到了不少.
不说 SHM , 普通内存也有分配次数限制, 所以要做内存池, 当时我就做了一个内存池存放 shm.
shm 不得不考虑线程, 以至于当时的项目用 loki 技术封装了信号量和内存池再加上接口. 现在回想起来, 如果用户和项目经理要求不是那么 BT 的话(编译期映射 struct -_-! ), 完全可以做完整个项目.

zengjin8310 发表于 2006-1-9 18:35

[QUOTE=DarkSpy] 而且还要求给接口客户端程序员能将 struct 的数据放入我的接口内, 能映射一份 struct, 在编译时期搞定[/QUOTE] 没看明白你什么意思。
难道客户的struct跟你不是约定好的?如果没有约定好, 怎么可能编译期搞定。除非象java, C#一样有反射机制

thinkry 发表于 2006-1-13 17:39

如果性能要求高,一般都是单进程模型,进程间通过共享内存通讯。当然,这个单进程可以fork多个,每个进程只处理一个范围的数据,这样的话,多个进程之间没有互斥,服务器有多个CPU,自然要好好利用。

共享内存还有个好处,服务器重新启动不会丢失运营数据

1、在STL中,可以通过自定义Allocaltor来实现在共享内存中分配
2、建议自己实现一套共享内存操作类。例如:
CMemoryPool为内存池分配回收类,负责Alloc和Free内存块
CMap和CSet利用分配的内存块来组织map和set,算法上有现成代码参考,应该不复杂

甚至可以实现这种结构:先在Hash表(也是基于共享内存的)中查找,如果不存在,则在对应的CSet和CMap中查找。

zengjin8310 发表于 2006-1-13 20:43

[QUOTE=thinkry]如果性能要求高,一般都是单进程模型,进程间通过共享内存通讯。当然,这个单进程可以fork多个,每个进程只处理一个范围的数据,这样的话,多个进程之间没有互斥,服务器有多个CPU,自然要好好利用。

共享内存还有个好处,服务器重新启动不会丢失运营数据

1、在STL中,可以通过自定义Allocaltor来实现在共享内存中分配
2、建议自己实现一套共享内存操作类。例如:
CMemoryPool为内存池分配回收类,负责Alloc和Free内存块
CMap和CSet利用分配的内存块来组织map和set,算法上有现成代码参考,应该不复杂

甚至可以实现这种结构:先在Hash表(也是基于共享内存的)中查找,如果不存在,则在对应的CSet和CMap中查找。[/QUOTE]
1。大家现在都已经知道可以用这个方案, 如果楼上不吝, 请把代码发上来

2。也许你是一个高手, 那么请把你找到的现成代码放上来,自己实现所谓的 CMap, CSet, 以及Hash的代码, 哪怕是一个有那么点意思的代码。兄弟还是多做点问题少谈点主7义的好。任何事情并不是想想能就能作出来得

dearvoid 发表于 2006-1-13 21:50

[QUOTE=zengjin8310]1。大家现在都已经知道可以用这个方案, 如果楼上不吝, 请把代码发上来

2。也许你是一个高手, 那么请把你找到的现成代码放上来,自己实现所谓的 CMap, CSet, 以及Hash的代码, 哪怕是一个有那么点意思的代码。兄弟还是多做点问题少谈点主7义的好。任何事情并不是想想能就能作出来得[/QUOTE]
:) interesting :)

zengjin8310 发表于 2006-1-13 22:24

[QUOTE=dearvoid]:) interesting :)[/QUOTE]挑衅别人,跟接受别人的挑衅是促使自己飞快进步的一种手段 :)

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.