C++线程安全分析

C++线程安全分析 除了通过code review或者test来检测线程安全,有没有其它更好的办法? 答案是存在的,通过clang即可以进行这种检测,编译器对存在的线程安全问题会给出警告。 这种分析方法由Google开发,已经被Google大规模应用,参考 https://static.googleusercontent.com/media/research.google.com/zh-CN//pubs/archive/42958.pdf 示例example.cpp: #include “mutex.h” class BankAccount { private: Mutex mu; int balance GUARDED_BY(mu); void depositImpl(int amount) { balance += amount; // WARNING! Cannot write balance without locking mu. } void withdrawImpl(int amount) REQUIRES(mu) { balance -= amount; // OK. Caller must have locked mu. } public: void withdraw(int amount) {…

type 与 RTTI

时常,我们在程序中经常出现这样的switch或者if-else分支: if (pobj->IsKindOf(Circle)) else if (pobj->IsKindOf(Rectangle)) 等。其中上面的IsKindOf也可能是我们自定义的GetType(),或者是C++标准中的dynamic_cast。 不管怎么样,这是十分不好的设计/风格。 原因很简单,要添加一个新的类型,所有这些条件判断的地方都需要做更改;反之,使用多态只需要添加一个SubClass(当然,也可以在类层次上作一些调整)。 关于RTTI, google是这么认为的: 运行时类型识别(Run-Time Type Information, RTTI) 我们禁止使用 RTTI。 定义:RTTI 允许程序员在运行时识别 C++类对象的类型。 优点: RTTI 在某些单元测试中非常有用,如在进行工厂类测试时用于检验一个新建对象是否为期望的动态类型。 除测试外,极少用到。 缺点: 运行时识别类型意味著设计本身有问题, 如果你需要在运行期间确定一个对象的型类, 这通常说明你需要重新考虑你的类的设计。 结论: 除单元测试外, 不要使用RTTI, 如果你发现需要所写代码因对象类型不同而动作各异的话, 考虑换一种方式识别对象类型。 虚函数可以实现随子类类型不同而执行不同代码,工作都是交给对象本身去完成。 如果工作在对象之外的代码中完成,考虑双重分发方案,如Visitor 模式,可以方便的在对 象本身之外确定类的类型。 如果你认为上面的方法你掌握不了,可以使用RTTI,但务必请三思,不要去手工实现一个 貌似 RTTI 的方案(RTTI-like workaround),我们反对使用 RTTI,同样反对贴上类型 标签的貌似类继承的替代方案。 MFC的CObject::IsKindOf() 明确的指出Do not use this function extensively because it defeats the…

STL之争

以前,是否使用STL是有争议的,因此很多公司都实现了自己的一套STL。 其实STL有很多有意思的设计,比如实现了数据结构和算法的分离,这也是STL设计的核心思想。 在实现上,STL源代码也是能够给人一些启发的。比如sort算法的实现(这应该不是STL的开创),sort主要采用快速排序,对于初步有序的短系列,采用插入排序,对于快速排序的极端情况,还可能使用堆排序。 性能方面,STL作为通用库,一般来说效率还是比较高的。但是,在大型游戏领域和内存受限领域,以及由于STL在不同平台上的实现不同,其性能还需要改进。关于这一点,可以参考http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html这篇论文,论文还提供了一个性能对比图。 扩展性上,个人认为,仿函数,适配器还是有比较好的扩展性,Allocator(1998 ISO C++)则争议很大,上述论文和http://www.openstd.org/jtc1/sc22/wg21/docs/papers/2005/n1850.pdf这篇论文有比较详细的解释。 易用性上,STL同样备受争议。这主要表现在: (1)需要对库的实现有相当的理解,由于依赖于模版与泛型,然后又加上C++语言,滥用极可能带来性能的严重损失,难以发现的一些Bug等。 (2)调试的不方便,源码也缺乏文档和注释。 (3)一些局部的瑕疵, 比如缺少像树这种层级结构的容器,比如list的sort函数也违背了数据结构和算法的分离思想。 总而言之,作为通用库,STL还是比较不错的,而在某些对性能要求更高的领域,最好慎用。 对STL的改进和替换方面方面,可以参考: EASTL: EASTL依然沿用STL的基本思想,在实现上改进了STL,是一个性能更高,更易于调试的STL。 Doom3: 完全抛弃了迭代器,是一个比较简单,但是非常实用的STL。