一个包从共享内存到达服务器

一个包到从共享内存到GS流程
上次说到一个包从共享内存池取到一个包之后放入共享队列中
hr = m_spShareMemInter->pushA(sd);
看看GS这边是如何取包的
主线程创建了一个子线程
void GameServer::ProcessThread()
{
    try
    {
        ProcessThreadTry();
    }
    catch (...)
    {
        DWORD dwErrno = GetLastError();

        MessageBox(NULL, L"GameServer::process_thread异常", L"异常", MB_OK);
    }
}

void GameServer::ProcessThreadTry()
{
    int nCount = 0;
    packet Pkt;
    Pkt.data = new char[1024 * 100];//事先分配内存
    I_TimerFactory* pTimeFactory = GetPlug(TimerFactory);

    for (;;)
    {
        ProcMapSendData();//map发过来的数据

        m_spAsynDBC->Drive();//数据库回调

        bool bRcvDataRet = ProcessLoop(Pkt);//网络层的数据,现在只看这个
        ProcMapSendData();
    }
    //...(下面还有很多,暂时不看)
}
if(!m_spShareMemInter->popB(tmpShareData))来看看这个popB的实现

bool shareMemInterOneway::popOut(shareData& sd)
{
    {
        if(m_ShareMemQue->size() == 0)//m_ShareMemQue就是交互的真正的队列,注意他里面保存一个内存池中的地址
            return false;
    }
    {
        scoped_lock<interprocess_mutex> lock(m_mem镜像->mutex);//进程锁
        if(m_ShareMemQue->size() == 0)
            return false;

        auto sd2 = m_ShareMemQue->front();
        m_ShareMemQue->pop_front();
        sd.size            = sd2.size;
        sd.channel_id    = sd2.channel_id;
        sd.is_data        = sd2.is_data;

        if(sd2.is_data)
        {
            try
            {
                memcpy(sd.data, m_ProcessMemPool.convertAdd(sd2.total_size, sd2.index), sd.size);//从内存池中拷贝出来
            }
            catch(...)
            {
                MessageBox(NULL, L"shareMemInterOneway::popB", L"1ooo", MB_OK);
            }
        }

        m_ProcessMemPool.pushPkt(sd2);//归还内存池中的内存
    }

    return true;
}

bool GameServer::ProcessLoop(packet& rPkt)
{
    if(false == m_spDataLayer->Recv(rPkt))
        return true;//没数据了

    if(rPkt.is_data)
    {
        if(!rPkt.data)
            return false;

        GameChannel* pGC = m_vecChannel[rPkt.channel_id];//根据channelid确定是哪个channel,一个玩家对应一个channel
        if(pGC)
            pGC->OnReceiveData(rPkt.data, rPkt.size);

        m_LiveMgr.OnLive(rPkt.channel_id);
    }
    else//其他事件如连接断开,都是libevent事件
    {

    }
}
//一个包历经千辛万苦才打到服务器,对于到时怎么调用不同的函数,随后在看
时间: 2024-10-13 11:41:49

一个包从共享内存到达服务器的相关文章

Linux进程间通信(IPC)编程实践(十一)System V信号量---实现一个先进先出的共享内存shmfifo

使用消息队列即可实现消息的先进先出(FIFO), 但是使用共享内存实现消息的先进先出则更加快速; 我们首先完成C语言版本的shmfifo(基于过程调用), 然后在此基础上实现C++版本的ShmFifo, 将1块共享内存与3个信号量(1个mutext信号量, 1个full信号量, 1个empty信号量)封装成一个类ShmFifo, 然后编写各自的测试代码; shmfifo说明: 将申请到的共享内存作为一块缓冲区, 将该内存的首部(p_shm到p_payload的内容)格式化为如上图所示的形式; 读

一个包的net到gs流程

再来看看一个包走共享内存的流程 先来看看net进程这块如何处理的 {//用shareData这种类型封装刚才从无锁队列中取到的包 shareData sd; sd.channel_id = pkt.channel_id; sd.data = pkt.data; sd.is_data = pkt.is_data; sd.size = pkt.size; auto hr = m_spShareMemInter->pushA(sd);//将这个包放入共享内存中 } //具体看下是如何放入共享内存的 b

linux 进程通信之 共享内存

共享内存是被多个进程共享的一部分物理内存.共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容. 关于共享内存使用的API key_t ftok(const char *pathname, int proj_id); #在IPC中,我们经常用一个 key_t 的值来创建或者打开 信号量,共享内存和消息队列.这个 key_t 就是由ftok函数产生的. pathname:指定的文件名,该文件必须是存在而且可以访问 proj_

进程通信之共享内存

共享内存 共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存.进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一样.而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程. 共享内存并未提供同步机制,也就是说,在第一个进程结束对共享内存的写操作之前,并无自

进程间通信(9) - 共享内存(System V)

1.前言 本篇文章的所有例子,基于RHEL6.5平台(linux kernal: 2.6.32-431.el6.i686). 2.介绍 共享内存也是一种IPC,它是目前最快的IPC,它的使用方式是将同一个内存区映射到共享它的不同进程的地址空间中,这样这些进程间的通信就不再需要通过内核,只需对该共享的内存区域进程操作就可以了. 共享内存与其他的进程间通信最大的优点是:数据的复制只有两次,一次是从输入文件到共享内存区,一次从共享内存区到输出文件.而其他的则是需要复制4次:服务器将输入文件读入自己的进

linux使用共享内存通信的进程同步退出问题

两个甚至多个进程使用共享内存(shm)通信,总遇到同步问题.这里的“同步问题”不是说进程读写同步问题,这个用信号量就好了.这里的同步问题说的是同步退出问题,到底谁先退出,怎么知道对方退出了.举个例子:进程负责读写数据库A,进程B负责处理数据.那么进程A得比进程B晚退出才行,因为要保存进程B处理完的数据.可是A不知道B什么时候退出啊.A.B是无关联的进程,也不知道对方的pid.它们唯一的关联就是读写同一块共享内存.正常情况下,进程B在共享内存中写个标识:进程A你可以退出了,也是可以的.不过进程B可

共享内存基础

shmget int shmget(key_t key, size_t size, int flag); key: 标识符的规则 size:共享存储段的字节数 flag:读写的权限 返回值:成功返回共享存储的id,失败返回-1 key_t key-----------------------------------------------    key标识共享内存的键值: 0/IPC_PRIVATE. 当key的取值为IPC_PRIVATE,则函数shmget()将创建一块新的共享内存:如果ke

Linux共享内存使用常见陷阱与分析 - 51CTO.COM http://os.51cto.com/art/201311/418977_all.htmIPC---共享内存

共享内存就是允许两个或多个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据时,不需要在客户进程和服务器进程之间幅值,因此是最快的一种IPC.不同进程之间共享的内存通常安排为同一段物理内存.进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一样.而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程. 注意:共享内存并未提供同步机制,也就是说,

Boost:shared_memory_object --- 共享内存

什么是共享内存 共享内存是最快速的进程间通信机制.操作系统在几个进程的地址空间上映射一段内存,然后这几个进程可以在不需要调用操作系统函数的情况下在那段内存上进行读/写操作.但是,在进程读写共享内存时,我们需要一些同步机制. 考虑一下服务端进程使用网络机制在同一台机器上发送一个HTML文件至客户端将会发生什么: 服务端必须读取这个文件至内存,然后将其传至网络函数,这些网络函数拷贝那段内存至操作系统的内部内存. 客户端使用那些网络函数从操作系统的内部内存拷贝数据至它自己的内存. 如上所示,这里存在两