c++的线程安全静态检查

在阅读leveldb源码的过程中,发现很多成员变量被GUARDED_BY修饰,如下:

struct IterState {
  port::Mutex* const mu;
  Version* const version GUARDED_BY(mu);
  MemTable* const mem GUARDED_BY(mu);
  MemTable* const imm GUARDED_BY(mu);

  IterState(port::Mutex* mutex, MemTable* mem, MemTable* imm, Version* version)
      : mu(mutex), version(version), mem(mem), imm(imm) {}
};

宏定义如下:

#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#else
#define THREAD_ANNOTATION_ATTRIBUTE__(x)  // no-op
#endif

#endif  // !defined(THREAD_ANNOTATION_ATTRIBUTE__)

#ifndef GUARDED_BY
#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
#endif

#ifndef PT_GUARDED_BY
#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
#endif

通过翻阅资料,发现这是c++静态检测对应的变量是否有对应的mutex保护的方法。

只要在代码中通过代码注解(annotations )告诉编译器哪些成员变量和成员函数是受哪个 mutex 保护,这样如果忘记了加锁,编译器会给警告。因为在后续维护别人的代码时候,往往不像原作者那样深刻理解设计意图,特别容易遗漏线程安全的假设

使用方法也很简单,我们可以通过clang增加编译参数-Wthread-safety -Werror,获取有关线程安全的warning。

而leveldb使用的是abseil-cpp版本,使用方法相同

参考链接

  1. Thread Safety Analysis
  2. 现代 C++ 开发(1):线程安全注解
  3. C/C++ Thread Safety Analysis
  4. thread_annotations.h
  5. Enable thread safety annotations in open source version.

你可能感兴趣的:(C/C++技术,c++,clang)