peakzhang 发表于 2008-7-15 23:36:46

也谈ACE_Singleton

在使用ACE_Singleton时遇到一个很困惑的问题:
我在SessionPool.dll中的SessionPool.h和SessionPool.cpp中定义了一个类SessionPool,并在SessionPool.h中定义如下语句:
typedef ACE_Singleton<SessionPool,ACE_Null_Mutex> SESSION_POOL;
SessionPool.dll编译没问题。

我的EXE使用B.dll和C.dll,而这两个dll都要访问在SessionPool.dll中定义的单体对象。然而不幸的是,我发现B.dll和C.dll为我分别创建了2个ACE_Singleton!!!分析原因,大概是模板类实例化的问题吧。

这样的话,我在B.dll中为单体对象添加数据后,就无法在C.dll代码中继续处理。


解决方案一:将SessionPool建立成单体。

SessionPool* &SessionPool::instance_i()
{
       staticSessionPool* _instance = 0;

       return _instance;
}

SessionPool* SessionPool::Instance()
{
       SessionPool* &_instance = SessionPool::instance_i();

       if(0 == _instance){
            _instance = new SessionPool();
       }
    return _instance;
}

void SessionPool::Close()
{
       SessionPool* &_instance = SessionPool::instance_i();

       delete _instance;
       _instance = 0;
}

然后在各处调用SessionPool::Instance()就行了。但这种方法明显的问题是必须显式关闭,不如ACE_Singleton方便;还有无法使用ACE_Singleton的锁同步机制。


解决方案2:在SessionPool.h中建立类SESSION_POOL并输出:
class SP_Export SESSION_POOL : public ACE_Singleton<SessionPool,ACE_Null_Mutex>   
{
};
而不用typedef,一切解决啦。试了半天才想起来试一下:(


后来一想,这个问题倒可以在不同dll中实现“局部”的ACE_Singleton。不过和编译器能力有关,有点危险。

peakzhang 发表于 2008-7-15 23:36:59

DLL中,是推荐用ACE_Unmanaged_Singleton的。

andywangcn 发表于 2010-9-10 21:18:57

路过此地,学习学习
页: [1]
查看完整版本: 也谈ACE_Singleton