从零学习开源项目系列(四)LogServer源码探究

这是从零学习开源项目的第四篇,上一篇是《从零学习开源项目系列(三) CSBattleMgr服务源码研究》,这篇文章我们一起来学习LogServer,中文意思可能是“日志服务器”。那么这个日志服务器到底做了哪些工作呢?

我们在Visual Studio中将LogServer设置为启动项,然后按F5将LogServer启动起来,启动成功后显示如下图:

从上图中,我们可以到大致做了三件事:

我们来验证一下这三件事的细节。我们再Visual Studio中将程序中断(【调试】菜单-【全部中断】,快捷键Ctrl + Alt + Break)。然后在线程窗口查看这个程序所有的线程,如下图所示:

所有用红色旗帜标记的线程都是用户线程,我们可以查看这些线程的调用堆栈。我们从最上面的主线程开始:

切换到main函数,我们可以看出这里是一个循环:

这里一个是初始化动作,一个循环中Update动作,它们具体做了些什么,我们先不管,我们先看其他线程做了什么,再回过头来看这里的代码。

我们接着看下一个线程的内容:

从调用堆栈来看,这是一个使用boost::thread启动的线程,这个线程函数代码如下:

我们先看下这个线程函数做了什么,主要是m_BeginInThreadCallbackConsume()函数,看下Consume()函数:

这段代码很好理解,先使用条件变量挂起当前线程,条件变量触发后,如果消费者和生产者共有队列m_Queue中有数据,将公用的队列m_Queue临时倒换到本地的一个局部队列m_SwapQueue中,然后挨个处理队列m_SwapQueue中的数据。

这个线程在哪里创建的呢?通过搜索线程函数,我们找到如下代码:

在上面这个函数中添加断点,重启下程序,很快会触发断点,我们看下断点触发时的调用堆栈:

通过调用堆栈,我们发现这个线程在一个全局变量的构造函数中初始化的,这个全局变量在DllMain()函数中初始化:

而这个dll是ELogging项目生成的:

也就是说,这是一个与日志处理相关的线程。生产者产生日志记录,然后由这个线程作为消费者,来处理日志。

我们接着看下一个线程的内容:

这也是一个循环,先看下_ProcRequests()函数:

这段函数的逻辑也是比较容易懂,先从一个队列中取出数据,然后处理,只不过这些数据都是与连接相关的信息。

再看下while循环中第二个函数_ProcEvents:

这个函数,对上一个函数中发起的连接结果做出判断并处理。如果连接成功,则向完成端口上投递一个recv事件。这个循环的代码,我建议读者好好研究一下,非常好的重连实例,同时也组合了完成端口的模型,还有一些重要的网络编程细节(如nodelay选项等)。

那么这个线程在哪里启动的呢?通过搜索OnExecute函数名我们发现真正的线程函数:

进而搜索到:

我们在CConnectCtrl::Init()处加个断点,然后重启一下程序,看下调用堆栈:

CUCODENETWin::_InitComponent()中我们看到整个网络通信框架的初始化,初始化CConnDataMgrCEventMgrCConnectCtrlCIocpCtrl

而所有的这些初始化,都是在所谓的CLogNetSessionMgr中初始化的:

我们最终追溯到最上层的代码中:

到这里,终于找到家了。

最后一批介绍的四个线程是完成端口线程,如下图所示:

精华部分全在其线程函数中:

我始终觉得,完成端口模型即使不从事Windows开发的linux服务器开发人员应该也要掌握一下。尤其是linux服务器开发人员需要给客户端人员设计网络通信层的企业。

我们看下,这四个线程在哪里启动的。

同样的方法,我们通过搜索,先找到:

进而进一步找到:

然后同样的方法在CIocpCtrl::Init()处加个断点,重新跑下程序,得到如下调用堆栈:

我们上文中已经介绍过了,这里就不再重复说明:

通过分析,我们知道LogServer大致的技术框架,业务细节和技术细节,我们在后面的文章中会接着介绍。我们当前的目的是快速把所有的服务的技术框架给熟悉一遍。

您可以继续阅读下一篇文章《从零学习开源项目系列(五)SSBattleMgr源码探究》。

欢迎关注公众号『easyserverdev』。如果有任何技术或者职业方面的问题需要我提供帮助,可通过这个公众号与我取得联系,此公众号不仅分享高性能服务器开发经验和故事,同时也免费为广大技术朋友提供技术答疑和职业解惑,您有任何问题都可以在微信公众号直接留言,我会尽快回复您。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180523G0765N00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券