在写这篇文章前,我突然想到以前流行了一段时间的服务器面试题:当一个BUG只有几百万分之一的概率会出现,怎么办?这个问题在这个BUG里只是毛毛雨而已,因为这次的BUG的出现概率是夸张的三亿分之一

由于之前整理的服务器框架已经完成了,就需要用各种静态分析工具跑一遍。原来的llvm+clang的编译脚本是从GCC那个脚本copy过来然后改的,使用的时候各种问题。所以干醋重新折腾一遍,重写了。

近期仍然在搭建完整的游戏服务器架构。基于atsf4g(asynchronously-tree server framework fo game)的完整解决方案终于接近完成。基本框架之前其实已经做完了,但是之前解决的只是基本的框架层代码,不包含任何特定的交互模型、协议模型、配置服务等等。这回就整理了一个只包含登入登出逻辑的完整工程,另外优化了一些小细节和周边工具的支持。

好久没写blog了。最近空闲时间都在加紧完成atframework框架。总算是搞完了,并且搭建了一个静态介绍页。以后有空慢慢加文档进去。

主页: https://atframe.work/ Github: https://github.com/atframework/

目前这个项目已经是一个小型游戏服务器的完整框架,包括服务器间实例的管理、客户端和服务器的内部协议和通信机制。并且实现了纯C的port。 然后https://github.com/atframework/atsf4g-co/tree/master/sample/atgw_cli_inner_hello里提供了c++的客户度端的代码示例,https://github.com/atframework/AtgwInnerCli-CSharp里提供了C#的客户端代码示例。 使用的都是同一个纯C的协议porting。这样无论cocos还是unity框架接入都不困难了。其他的框架也可以直接用这个纯C的porting来接入。

我们目前的游戏第一次测试的时候笔记送匆忙,导致上线之后频繁更新。 比如BOSS战由于大区的人数和预期不一样导致的难度调整,或者是任务链或者数值调整,再加上一些BUG。

这个问题起源于以前给客户端写的一个log模块,然后里面为了线程安全且多线程下不互相写乱,并且因为这些系统基本都用比较高版本的编译器,都支持C++11了,所以就用了C++11的TLS功能。

前言

之前写了个C++的协程框架libcopp,底层使用的是boost.context实现,然后剥离了对boost的依赖。然而这样意味着我必须时常跟进boost.context的更新。

顺带提一下这个协程库已经在我们线上服务器版本中使用了。

从最初的boost版本(我忘了从哪个版本开始了)一直到1.60版本,boost.context的变化都不大,都只是补全一些新的架构和体系结构,还有就是修复一些小细节的BUG,再就是增加了对valgrind的支持(之前写过一个Merge记录提到过)。新增的功能也只有execution_context(现在叫execution_context_v1),这个东西我的libcopp里其实包含了这个功能,并且本身做得比它要功能丰富,所以没有接入的必要。另外在1.60版本的时候尝试使用Windows里的fiber(当然默认是关闭的),在1.61版本里被移除了。这些细节都不是特别重要,主要还是1.61版本的变化。

libatbus

经过茫茫长时间的编写+过年在家无聊补充和修正单元测试,再加上这两天的整理,终于把以前的这个关于服务器通信中间件的基本功能和相应的单元测试完成啦。还是可以热烈庆祝一下的。

小记最近踩得两个C++坑

记一下最近踩得两个C++独有的暗坑,其中一个和ABI相关。第二个坑其实之前研究过,但是没有实例,这次算是碰到了个典型的实例。

坑一:常量引用失效

在项目中碰到的实例的大致流程是:

LLVM和Clang工具链的生成配置文件写得比较搓,所以略微麻烦,另外这个脚本没有经过多环境测试,不保证在其他Linux发行版里正常使用。

如果第一次执行出现安装失败,可以再执行一次。llvm的安装脚本问题多多

目录

C++ 的Lambda表达式

C++ 11 标准发布,各大编译器都开始支持里面的各种新特性,其中一项比较有意思的就是lambda表达式。

语法规则

C++ 11 Lambda表达式的四种声明方式

C++11标准里有动态模板参数已经是众所周知的事儿了。但是当时还有个主流编译器还不支持。 但是现在,主要的编译器。VC(Windows),GCC(Windows,Linux),Clang(Mac,IOS)都已经支持了。所以就可以准备用于生产环境了。 type_traits没啥好说的。主要是一些静态检测。主要还是要看动态模板参数和他们两的结合使用上。 动态模版参数标准文档见: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdfhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf 虽然贴出来了。估计是没人看得。所以就直接说重点。

这是我对C++新特性系统学习的最后一部分,之后就靠实践中再来看新标准的新特性啦。

在之前,我对这部分没太在意,直到看到了一篇文章 [http://blog.csdn.net/pongba/article/details/1659952](http://blog.csdn.net/pongba/article/details/1659952) 才意识到,C++的多线程操作也是个麻烦的问题。

简而言之,C++编译器在进行编译优化的时候,认为当前是单进程的,并且遵循**可观察行为**(Observable Behavior)不变的原则。就是说在可观察行为不变的情况下,操作是可以被改变顺序的,而单进程可观察行为不变,不代表在多进程的情况下仍然不变。还是上大牛的例子:

_**例子一:**_

完全可以优化成

C++在效率上有个硬伤。我们知道C#和Java对于类传递都是以引用的方式,而C++默认都是传值。在传值过程中就经常会进行复制构造,这完全没必要而且浪费CPU,为了解决这种问题,于是乎C++11 增加了一个新的非常数引用(reference)类型,称为右值引用(R-value reference)。我就专门看了一下关于右值引用的东西。 右值引用在GCC 4.3之后开始支持,VS 2010(VC 10.0)已经支持,再前一点的VC版本没试过所以不知道。 右值引用的申明标记为T &&,主要用于处理临时变量,比如函数返回的变量(暂时想不出其他例子,忽略返回值优化吧,(命名)返回值优化参见http://efnetcpp.org/wiki/Return_value_optimization,再说返回值优化能力有限是吧,比要求如单返回语句、不能使用异常等等),避免复制构造。同时在析构的时候就不会析构这个临时变量,从而提升效率。 上代码:

这各部分主要是一些很实用和在一些地方帮助编译器自动推断类型的库和函数 首先是引用包装 类名 template< class T > class std::reference_wrapper; 这个类保存了对一个类实例、(成员)函数(指针) 构造时必须传入所引用的对象或引用对象的右值引用 主要方法有 =号操作符, 用于重新绑定引用对象 类型转换操作符, 用于转换为模板目标类的引用类型 get方法, 用于获取引用的对象 ()操作符, 用于执行引用的函数