sunlock 发表于 2010-9-1 22:34:25

ACE使用过程的2个问题

(1)一个服务器我用ACE的WFMO _Reactor在windows下很好的工作,但是考虑到跨平台及62个最大连接的问题,考虑用select_Reactor,改成select_reactor后也能正常工作,但不知何故,只要有连接,cpu占用比较大,8核,占用13%,而用原来的基本无cpu占用,不知道是怎么回事(我还没有用前摄器,因为我的服务器不需要那么大的并发,500个足矣)
(2)用了一个简单的定时器,还没自己去弄定时器队列,也就是ACE_Event_Handler.能正确起到定时器作用,但是销毁的时候有时发生死锁现象。我说的销毁是调用Cancel,是基于反应器的实现。
不知道大家碰到过这样的问题没有

sunlock 发表于 2010-9-2 11:11:38

怎么没有人回答呢?

galaxy666 发表于 2010-9-2 12:01:30

本帖最后由 galaxy666 于 2010-9-2 12:44 编辑

不知道什么原因 不过倒是有别的方法解决跨平台及连接数最大62问题
1、跨平台
读配置文件或者预处理,不同平台用不同实现,windows下WFMO _Reactor,其他平台下select_reactor

2、最大连接62
建一个类CReactor封装ACE_WFMO_Reactor,CReactor中有个计数器,每注册一个句柄计数器+1,当计数器大于62时候,重新new CReactor,以此类推。

winston 发表于 2010-9-2 17:16:09

select模式就是在高负载的时候,效率差,大家都知道。
如果可以,就不要用select,用那个dev_poll实现。内部是EPOLL方式处理。

sunlock 发表于 2010-9-7 10:13:16

回复 4# winston

我在windows下用呢?

sunlock 发表于 2010-9-7 10:15:56

to:
galaxy666
你说的第二条做法,保险吗?比如泄漏啥的考虑

modern 发表于 2010-9-7 10:17:53

3楼解决最大62连接的办法太有想法了。

freeeyes 发表于 2010-9-7 10:38:08

在windows下可以使用Proactor模式。Proactor实际是调用IOCP,在windows下比较能发挥它的长处。

sunlock 发表于 2010-9-7 12:37:10

实际上,ACE的多路复用实际上是另一种的完成事件队列机制,如果按照galaxy666的说法可用,用Reactor和Proactor应该差别不大,唯一的差别是Proactor用的是异步IO。事件上windows的完成端口并不一定必须用异步IO的,完全可以用windows的完成端口自己实现个事件多路分离复用

galaxy666 发表于 2010-9-7 16:55:38

本帖最后由 galaxy666 于 2010-9-7 17:03 编辑

class CReactor
{
public:
        int increaseCount()
        {
                if (m_nCurRegisterCount<62)
                {
                        ++m_nCurRegisterCount;
                }
                else
                {
                        return -1;
                }

                return m_nCurRegisterCount;
        }
        int decreaseCount()
        {
                if (m_nCurRegisterCount>0)
                {
                        --m_nCurRegisterCount;
                }
                else
                {
                        return -1;
                }

                return m_nCurRegisterCount;
        }

        bool isFull()
        {
                bool bFull = (m_nCurRegisterCount == 62);
                return bFull;
        }
private:
        int m_nCurRegisterCount;
        ACE_Reactor* m_pReactor;
};

class CReactorManager
{
public:
        CReactor* applyReactor()
        {
                CReactor* pReactor = findFreeReactor();
                if (pReactor)
                {
                        pReactor->increaseCount();
                }
                else
                {
                        pReactor = new CReactor;
                }

                return pReactor;
        }
        void releaseReactor(CReactor* pReactor)
        {
                if (m_listReactor.find(pReactor)!=m_listReactor.end())
                {
                        int nRet = pReactor->increaseCount();
                        if (-1 == nRet)
                        {
                                delete pReactor;
                                pReactor = NULL;
                        }
                        //链表里面也要删除
                }
        }


private:
        CReactor* findFreeReactor()
        {
                list<CReactor*>::iterator it = m_listReactor.begin();
                CReactor* pReactor = NULL;
                for (;it!=m_listReactor.end();++it)
                {
                        pReactor = *it;
                        if (!pReactor->isFull())
                        {
                                break;
                        }
                }

                return pReactor;
        }
private:
        list<CReactor*> m_listReactor;
};


需要Reactor时向CReactorManager申请一个,不需要时也必须通过CReactorManager释放。
当连接数大于62时,CReactorManager就会new一个CReactor。如果一组Reactor的连接数没满,就用这个Reactor,但计数器要加1.
线程安全、内存释放自己处理。
代码没写全,应该能表达意思吧 呵呵
页: [1] 2
查看完整版本: ACE使用过程的2个问题