如何将其用于标准类型,例如std :: mutex and std :: lock_guard? sumex.h的示例代码注释自定义接口。我是否具有在此处定义的类型“静音”类型,并使用带注释方法的std :: mutex实现类,或者clang会以某种方式带来带注释的类型?
最近版本的clang,您可能不再需要包装STD :: Mutex,因为自2016年3月15日以来,线程安全注释已被添加。
这将clang线程安全注释添加到std :: Mutex和 std :: lock_guard,因此使用这些类型的代码可以直接使用这些类型 而不是必须包裹类型以提供注释。这些检查 当通过-Wthread -Safety启用时,提供简单但有用的静态 检查以检测潜在的种族条件。 请参阅
Http://clang.llvm.org/docs/threadsafetyanalysis.html简单地拥有-Wthread-safety
就足够了。
themplement提供的sutex.h文件中描述的接口,并使用std :: mutex类来做到这一点。即,这里是半完成的实施:Minor更改为
Mutex.h文件,以包括一个std :: mutex对象
class CAPABILITY("mutex") Mutex { private: std::mutex std_mutex; public: // Acquire/lock this mutex exclusively. Only one thread can have exclusive // access at any one time. Write operations to guarded data require an // exclusive lock.
然后在mutex.cpp
中实施其余的
#include "mutex.h"
void Mutex::Lock(){
this->std_mutex.lock();
}
void Mutex::Unlock(){
this->std_mutex.unlock();
}
bool Mutex::TryLock(){
return this->std_mutex.try_lock();
}
std::mutex
中的Mutex
示例类别的注释,可以像示例代码一样使用,进行一些修改和注意。
LIBC++
(LLVM的一部分的标准C ++库)作为您的标准C ++库。 一些叮当的安装使用libstdc++或其他库,但是Afaik没有其他库包含注释。 如果已安装了libc ++,但不是您使用的默认值,则可以使用选项
进行选择。
您必须在包含标准标头(或在带有
-stdlib=libc++
的命令行上)之前先进行
#define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
才能启用注释。
-D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
,GUARDED_BY
等,只是编译器实际使用的更繁琐的REQUIRES
语法周围的便利包装器。 libc ++标头无法定义便利包装器,因此,如果要使用它们,则应在示例中的示例
__attribute__
中复制它们;或定义您自己的类似的。
当然,您需要与
mutex.h
一起编译。
在此之后,示例代码可与
-Wthread-safety
更改为Mutex
,并且方法适当地更名为(std::mutex
Lock
等)。 trone在Godbolt
上:
lock
当用
#define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
#include <thread>
#include <mutex>
#if defined(__clang__) && (!defined(SWIG))
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#else
#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
#endif
#define GUARDED_BY(x) \
THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
#define REQUIRES(...) \
THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
class BankAccount {
private:
std::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) {
mu.lock();
withdrawImpl(amount); // OK. We've locked mu.
} // WARNING! Failed to unlock mu.
void transferFrom(BankAccount& b, int amount) {
mu.lock();
b.withdrawImpl(amount); // WARNING! Calling withdrawImpl() requires locking b.mu.
depositImpl(amount); // OK. depositImpl() has no requirements.
mu.unlock();
}
};
编译时,这应该在
clang++ -std=c++23 -stdlib=libc++ -Wthread-safety
线上发出警告:// WARNING!