专栏首页xingoo, 一个梦想做发明家的程序员CIOCPServer的数据结构定义及内存池方案

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);
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • CIOCP自定义帮助函数

                                                     1 客户连接列表                       ...

    用户1154259
  • IO处理线程

    客户IO处理,是在工作线程,_WorkerThreadProc中完成的 函数,在完成端口上调用GetQueuedCompletionStatus函数等待IO完成...

    用户1154259
  • Mybatis文档阅读笔记(明日继续更新...)

    今天在编写mybatis的mapper.xml时,发现对sql的配置还不是很熟,有很多一坨一坨的东西,其实是可以抽取成服用的。不过良好的组织代码,还是更重要的...

    用户1154259
  • CIOCP自定义帮助函数

                                                     1 客户连接列表                       ...

    用户1154259
  • “眼睛成长记“(一)--睁开双眼

    Now, let us witness the growth of eyes together!

    视界音你而不同
  • OpenCV在地图测试上的应用

    我们在以往的UI自动化测试中,可以通过获取页面元素进行封装组合成一系列模拟真人的操作,来完成UI方面的自动化测试,但是在地图业务测试中,这种方式是无法...

    用户5521279
  • 大流量冲击下,腾讯QQ客户端如何保障春节红包活动的用户体验?

    2020腾讯QQ春节红包主要以答题的玩法,结合中国传统文化(成语、诗词、对联、历史等)的方式进行,达到寓教于乐的效果。

    腾小云
  • 深度学习实战 cifar数据集预处理技术分析

    cifar数据集是以cifar-10-python.tar.gz的压缩包格式存储在远程服务器,利用keras的get_file()方法下载压缩包并执行解压,解压...

    算法与编程之美
  • Zipkin实现分布式链路追踪

    如今越来越多的互联网公司在架构上开始走向分布式,比如微服务,分布式数据库,分布式缓存等等。好处很明显,高扩展性,高可用,高性能。缺点也有比如分布式事务,分布式锁...

    每天学Java
  • SpringMVC--拦截器笔记

    SuperHeroes

扫码关注云+社区

领取腾讯云代金券