Category: C++

Use SublimeClang in SublimeText 3

SublimeClang is the greatest thing in ST3, at least in every C++ programmer’s mind: it is the only plugin in ST that supports C++ intelligent completion/jumping. However, the author of SublimeClang has moved to...

More

C++的反射机制小例

原来一直对“反射”这个概念不清楚,听别人提起过很多次,也有vczh这样的大牛号称在C++里实现了反射,我也不知道具体指的是什么。今天在SOLID里遇到一个具体问题,跟HJK讨论了一下,发现原来这就是反射机制。 简单的说,反射就是让对象获取关于自身的信息(如对象类型),而不需要在编写代码的时候提前知道这些信息。比如说,我们有一个对象a,其类型是A。一般来说,我要对a进行操作,需要先声明一个A& a_pointer,然后再来做事情。但是假设我们这时候不知道A这个类型,或者这个类型的头文件并未被引用,就无法对a进行操作了。如果我们可以获得a的类型信息,比如TYPEOF(a)& a_pointer, 那么我们就无需知道a的具体类型,或者引用A类型的头文件了。 C++并不直接支持反射特性,但是上述的场景在OO语言中会经常出现。考虑一个常见的场景。假设有如下的两个派生类,都由Base类派生而来 // a_class.h class A : public Base { public: A() {} virtual ~A() {} virtual void Produce(Base** x) {*x = new A;} }; // b_class.h class B :...

More

一个轻量级高性能日志类库的原型

Muduo网络库包含了一个轻量级的日志库,可达到超过100MB/s的本地文件写入速度。这个基本上已经达到SATA磁盘线速,满足实际应用中的需求。最近在SOLID系统的开发中,想借用Muduo的日志库来进行元数据(metadata)的输出,但是发现Muduo日志库并不支持同时向多文件进行写入:输出函数是全局的,所以输出行为(包括位置)是共享的;在异步日志类中也是共享了一个mutex。这些都导致Muduo日志库原生不支持多文件的输出。而在SOLID系统中,每种协议或者应用的输出格式是不一样的,放在一个文件显得杂乱而且数据库端也不好处理。 我首先尝试了修改Muduo本身:将输出函数变成Muduo::Logger类的成员而非全局,这样每次在使用LOG宏的时候就可以指定输出函数。然后将异步类中的mutex也搞成私有。后来发现核心问题在域LOG_INFO/LOG_ERROR这些宏实际上是生成了一个匿名的临时对象,这些对象的生命周期就在这条语句之后结束。通过析构函数的调用顺便可以进行文件flush等操作。这就要求修改后每次LOG_INFO时都要对输出函数进行重新赋值,这个开销还是有点大。同时在异步日志类中对mutex的依赖相当多,需要大量修改,还是决定重新造个轮子吧。 正好与Muduo网络库搭配的书到了,仔细研读了一下日志库的代码和相应章节,总结了Muduo可以做到磁盘线速写入的主要原因。 1. double-buffer结构,其实就是ping-pong结构。即前端(接收新日志)将日志写入BufferA中,后端(将日志输出到文件)不断的将BufferB中的日志写入文件,同时前端对BufferA做个判断,超过阈值大小就swap两个buffer,这样的好处是锁粒度相当小,前端只在swap的时候加锁,后端每次把BufferB转移到另一个临时变量后也可以释放锁。两个临界区的操作都是常数时间。这是Muduo高效的最主要原因。 2. 小细节。如时间格式化函数首先比较struct tm.tv_sec,相等的话就只修改tv_usec部分就好了,减少了很多格式化工作。时间部分的长度也是固定的,可以预先格式化等等。 按照以上设计概要,我简单实现了一个提供异步写入的日志类。这个类的对象生命周期可认为是永久,通过类型内部的线程进行持续的写入。简单结构如下。 class Log { private: FILE* file_; vstring name_; uint64_t now_size_; thread* thread_; void FormatTime(char t_time[]); void RollFile(); public: Log(vstring name) : name_(name), now_size_(0), now_buf_(), running_(false)...

More