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);
}
复制代码
posted @   xingoo  阅读(1364)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示