zoukankan      html  css  js  c++  java
  • CIOCPServer的数据结构定义及内存池方案

    为了避免频繁的申请释放内存,使用内存池来管理缓冲区对象客户上下文对象使用的内存。

    使用指针保存所有空闲的内存块,形成空闲列表

    申请内存时,这个指针不为NULL,就从空闲列表中取出一个来使用,如果取完,就真正的申请内存


                      1 缓冲区对象               

    程序使用CIOCPBuffer来描述per-IO数据,包含IO操作的必要信息,提交时,提交的就是CIOCPBuffer对象

    下面是申请缓冲区对象代码:

    CIOCPBuffer *CIOCPServer::AllocateBuffer(int nLen){
        CIOCPBuffer *pBuffer = NULL;
        if(nLen>BUFFER_SIZE)
            return NULL;
    
        ::EnterCriticalSection(&m_FreeBufferListLock);
        if(m_pFreeBufferList == NULL)
        {
            pBuffer=(CIOCPBuffer*)::HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CIOCPBuffer)+BUFFER_SIZE);
        }
        else
        {
            pBuffer = m_pFreeBufferList;
            m_pFreeBufferList = m_pFreeBufferList->pNext;
            pBuffer->pNext = NULL;
            m_nFreeBufferCount--;
        }
        ::LeaveCriticalSection(&m_FreeBufferListLock);
        if(pBuffer!=NULL)
        {
            pBuffer->buff = (char*)(pBuffer+1);
            pBuffer->nLen = nLen;
        }
        return pBuffer;
    }

    下面是释放缓冲区对象的代码:

    void CIOCPServer::ReleaseBuffer(CIOCPBuffer *pBuffer)
    {
        ::EnterCriticalSection(&m_pFreeBufferListLock);
        if(m_nFreeBufferCount<=m_nMaxFreeBuffers)
        {
            memset(pBuffer,0,sizeof(CIOCPBuffer)+BUFFERSIZE);
            pBuffer->pNext = m_pFreeBufferList;
            m_pFreeBufferList = pBuffer;
            m_pFreeBufferCount++;
        }
        else
        {
            ::HeapFree(::GetProcessHeap(),0,pBuffer);
        }
        ::LeaveCriticalSection(&m_pFreeBufferListLock);
    }

                      2 客户区上下文对象                    

    客户上下文对象便是per-Handle数据,包含了套接字的信息,服务器程序接收到一个新的连接,就为新连接创建客户上下文对象,以记录客户信息。

    代码差不多与缓冲区上下文对象差不多,释放的代码如下:

    void CIOCPServer::RealeaseContext(CIOCPContext *pContext)
    {
        if(pContext->s != INVALID_SOCKET)
            ::closesocket(pContext->s);
        CIOCPBuffer *pNext;
        while(pContext->pOutOfOrderReads !=NULL)
        {
            pNext = pContext->pOutOfOrderReads->pNext;
            ReleaseBuffer(pContext->pOutOfOrderReads);
            pContext->pOutOfOrderReads = pNext;
        }
        ::EnterCriticalSection(&m_pFreeBufferListLock);
        if(m_nFreeBufferCount<=m_nMaxFreeBuffers)
        {
            CRITICAL_SECTION cstmp = pContext->Lock;
            memset(pContext,0,sizeof(CIOCPContext));
            pContext->Lock = cstmp;
            pContext->pNext = m_pFreeContextList;
            m_pFreeContextList = pContext;
            m_nFreeContextCount++;
        }
        else
        {
            ::DeleteCriticalSection(&pContext->Lock);
            ::HeapFree(::GetProcessHeap(),0,pBuffer);
        }
        ::LeaveCriticalSection(&m_pFreeBufferListLock);
    }
  • 相关阅读:
    Android中使用File文件进行数据存储
    Android 获取 json
    Android服务之Service
    php
    宝塔数据库连接不上
    idea中使用github
    elasticjob 当当的分布式定时任务管理
    定时任务规则生成器
    MySQL中group_concat()函数的排序方法
    mysql 中关于怎么写 row_number()over(order by) 类似的功能支持
  • 原文地址:https://www.cnblogs.com/xing901022/p/2729484.html
Copyright © 2011-2022 走看看