GS与MS之间通信

GS与MS之间通信
注意GS与MS是两个线程,现在是每个map一个线程,他们之间是内部协议进行通信的,那既然是两个线程那如何通信呢,看了net进程通信这个就比较简单了
举个例子
m_pMap->Gs2MsData(gs2ms_add_player, m_nChannelId, (void*)&rActorEx, sizeof(rActorEx));//发送玩家上线包
void Map::Gs2MsData(int cmd, int channel_id, void* data, int len)
{
    MapPkt pkt;
    pkt.channelId = channel_id;
    pkt.data = m_memPool.popPkt(len);注意这个m_memPool是线程安全的队列,内部是boost无锁队列实现的
    memcpy(pkt.data, data, len);//不同线程需要内存拷贝,不可能使用同一块地址
    pkt.len = len;
    pkt.cmd = cmd;

    PushPkt(pkt);
}

void ThrTransData::PushPkt(MapPkt Pkt)
{
    for (;;)
    {
        if(m_gs2msPkts2.push(Pkt))//将包放入boost无锁队列中
            break;
        cxx11::this_thread::interruptible_wait(1);
    }
}
那看看MS这边是如何取的
在share初始化的时候开启了一个线程,这个线程可以说整个map的数据都是这里面处理的
bool ThrTransData::GetDataFromQueue(MapPkt* pPkt)
{
    if(m_gs2msPkts2.empty())
        return false;
    {
        MapPkt tmpPkt;
        if(m_gs2msPkts2.pop(tmpPkt))//从GS到MS这端的无锁队列中取包
        {
            *pPkt = tmpPkt;
            return true;
        }
        return false;
    }
    return true;
}
if(GetDataFromQueue(&Pkt))
{
    ProcessPkt(Pkt);//解析包调用相应函数
    m_memPool.pushPkt(Pkt.data, Pkt.len);//将内存池归还

    nCount++;
    if(nCount > 30)
    {
        nCount = 0;
        m_spTimerFactory->driveTimer();
    }
    continue;
}
//至此从GS到MS这边的包就是这样处理的

那从MS到GS的包
从Map需要发到GS的包也不多,还有一种通过GS转到map的
SendCmd2Gs(ms2gs_prop_mgr, nChannelID, pData, nLen);
void SendCmd2Gs(int nCmd, int nChannelId, void* pData, int nLen)
{
    MapPkt Pkt;
    Pkt.cmd = nCmd;
    Pkt.channelId = nChannelId;
    char* pszNewBuffer = new char[nLen];//这个是自己new的,发送到MS是从内存池中获取的
    memcpy(pszNewBuffer, pData, nLen);
    Pkt.data = pszNewBuffer;
    Pkt.len = nLen;
    PushData2GS(Pkt);
};

void PushData2GS(const MapPkt& Pkt)
{
    while(1)
    {
        if(m_quePkts2Gs.push(Pkt))//从MS发送到GS的队列
    }
}
那GS是如何去的呢
void Share::ProcMapSendData()//这个是GS驱动的
{
    if(!itMap.second->RecvData(Pkt))//从无锁队列中取包
        break;
    if(Pkt.cmd == ms2gs_转client_cmd)//针对包进行处理
    {
        OnTurnToClient(Pkt.channelId, Pkt.data, Pkt.len);
    }
}
//开来发包都是双向的,需要两个队列,这个在net那边也是的
//其次就是需要额外的内存放到队列中,因为不可能去操作同一块内存的,要么自己new,要么从内存池中分配
//MS与GS之间通过MapPkt进行通信,对于客户端和服务器通过protocol通信,通常是自己定义一块buf,然后打包到BUF中,net那块也是在内存池中分配一块然后存储这个buf,因为这个buf也是公用的
//刚开始不懂程序就是这些内存问题没有搞清楚
时间: 2024-10-25 13:54:55

GS与MS之间通信的相关文章

STM32W108无线射频模块多节点之间通信实例

STM32W108无线射频模块多节点之间通信实例 基于STM32W108的SimpleMac协议栈编写程序,实现多个无线节点之间的通信.节点分为SUN节点和PLANET节点,SUN节点使用STM32W108无线开发板,PLANET节点使用STM32W108无线数据采集节点,SUN节点可与PC机进行通信. 编程与实现 程序的设计基于SimpleMac协议栈进行,以下给出部分主要相关代码.该实例中的部分代码与第11章中的两节点通信实例代码相同,本章不再重复说明. 文件solar-system.c部分

进程与进程之间通信Manager

1 #!/usr/bin/env python 2 from multiprocessing import Process,Manager 3 4 #Manager进程与进程之间通信 5 def Foo(i,dic): 6 dic[i] = 100+i 7 print(dic.values()) 8 if __name__ == '__main__': 9 manage = Manager() 10 dic = manage.dict() 11 for i in range(2): 12 p =

同一个主机上的JVM实例之间通信

hadoop yarn里用了RPC调用.NM里面文件本地化类ContainerLocalizer用RPC心跳方式跟本机的ResourceLocalizationService通信. 用shared memory还要调到native层去,不知道会不会比tcp/ip快? 可以用文件,考虑锁的问题.但是文件貌似不能两边一起写,否则会乱的.也许弄两个文件,每个都是单工?这样还要监视文件是否发生变化. 还可以用剪切板,干扰比较严重 可以socket,socket是双工的,读写时都不用加锁防止另一边占用so

struts2 servlet之间通信

Servlet之间通信的方式有两大类,每个类有三种不同的方法 1.request 2.session 3.application 不实现ServletContextAware,SessionAware,ServletRequestAware这三个接口的通信 HttpServletRequest request = ServletActionContext.getRequest(); request.setAttribute("request_username", "usern

javaEE jsp与servlet之间通信

0.下载安装Opencv,当前版本为249. 1.下载Python,当前OPencv版本为249,不过其支持的最新版本的Python为2.7,所以可以下载276版本. 2.下载numpy,开始我使用了1.6,没有通过,错误如图.下载了最新的1.8.1版本. 3.将Opencv安装目录下opencv\build\python\2.7\x86中的cv2.pyd复制到python安装目录Lib\site-packages下. 4.找到opencv源文件内的draw.py运行. javaEE jsp与s

SM32W108无线射频模块两节点之间通信实例

SM32W108无线射频模块两节点之间通信实例 本文基于802.15.4/ZigBee的SimpleMac协议栈编写程序,实现两个STM32W108无线节点之间的通信.节点分为SUN节点和PLANET节点,SUN节点使用STM32W108无线开发板,PLANET节点使用STM32W108无线节点,SUN节点可与PC机进行通信. 程序设计与实现 程序的设计基于SimpleMac协议栈进行,根据官方提供的MAC协议栈示例代码进行的裁剪更改,第10章已对协议栈代码进行了解析,在此就不详细说明,以下只给

EventBus作为组件之间通信

1.为何要使用EventBus? 一般我们在不同activty等组件之间通信的时候,都用到了如下的模式: 就是定义一个接口,需要关注该事件的地方来实现这个接口.然后事件触发的地方来注册/取消注册这些对该事件感兴趣的控件,比如如下文章描述的情况: 使用Event Bus模式解耦Android App组件间通信 这样做的问题也是显而易见的,就是不同组件之间往往耦合的比较厉害,越来越多的接口也维护很麻烦,这样就需要用到EventBus模式来解决组件之低耦合的间通信 2.EventBus类库介绍 Eve

不通VLAN 之间通信

一.任务与目的 1. 实验任务: (1) 掌握和完成设置不同vlan间通过路由器互通的方法; (2) 完成同vlan间计算机的测试. 2. 实验目的: (1) 进一步熟悉交换机vlan间互通的配置方法; (2) 熟悉和掌握不同vlan间互通的测试方法. 二.原理(条件) 1.相关知识: (1) Vlan的工作原理; (2) 交换机与路由器的配置相关命令. 2.实验条件:(1) cisco pt软件.(2)1个路由器,1个二层交换机,4台pc. 三.实验拓扑图 swith0 上f0/1-12 属于

(转载) Android两个子线程之间通信

Android两个子线程之间通信 标签: classthreadandroid子线程通信 2015-03-20 17:03 3239人阅读 评论(0) 收藏 举报  分类: 个人杂谈 版权声明:本文为博主原创文章,未经博主允许不得转载. Android中,相信主线程和子线程之间的通信大家都不陌生了吧.在一次面试经历中被问到了两个子线程之间是如何进行通信的.哎呦!这可蒙住我了.后来回家研究了下,分享给大家. 其实android中线程通信无非就是handler和looper的操作. 一般情况下的主线