有没有办法设计这个"static class",使其是线程安全的?
Is there a way to design this "static class" so that it is thread-safe?
我有一个类,所有方法都是静态的,如下所示:
class A {
public:
static std::string getA() { GlobalData::alfa; }
static std::string sum(int x, int y) { ... }
static int convert() { ... }
};
我需要A可以是线程安全的。惠奇是更好的设计吗?我需要转换像这样的非静态方法中的所有方法吗?
class B {
public:
std::string getA() { g.alfa; }
std::string sum(int x, int y) { ... }
int convert() { ... }
private:
GlobalData g;
};
假设GlobalData是一个简单的POD,如下所示:
struct GlobalData
{
static std::string foo;
static int bar;
...
}
您可以保留类A
的原始布局,甚至将其更改为命名空间,但如果GlobalData
结构包含的数据必须特定于每个线程,则必须将其定义为线程本地存储:
struct GlobalData {
static thread_local std::string alfa;
// other members here
};
您可能需要调用一个函数来初始化每个线程所需的数据。
请注意,如果所有成员都已定义为static
:,您也可以将该结构转换为命名空间
namespace GlobalData {
thread_local std::string alfa;
// etc.
}
namespace A {
std::string getA() { return GlobalData::alfa; }
std::string sum(int x, int y) { /* ... */ }
int convert() { /* ... */ }
}
这提高了代码的可读性。
同样的规则应该适用于原始代码中任何全局范围的数据,这些数据必须是特定于线程的。
更好的设计是让A根本不使用静态实现。这意味着您将创建一个A实例,并通过依赖项注入在客户端代码中使用它。
然后,您可以使用标准同步原语实现对A数据的RW访问。
由于A具有静态状态,并且A不是注入的依赖项,因此在内部使用A的代码将在要添加到A的实现中的同步原语上同步。这引入了潜在的死锁,这些死锁在客户端代码中是完全不可见的,可能很难找到和诊断(取决于A的客户端代码交互的复杂性(。
相关文章:
- 如何将元素添加到数组的线程安全函数?
- C++中的线程安全删除
- 在std::thread中,joinable()然后join()线程安全吗
- 在c++队列中使用pop和visit实现线程安全
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- 全局变量 多读取器 一个写入器多线程安全?
- 共享队列的线程安全
- boost::文件系统::recursive_directory_iterator多线程安全
- 以线程安全的方式转换 C/C++ 中时区名称字符串的时区偏移量
- 线程安全运算符<<
- 如何使缓存线程安全
- C++线程安全:如果只有一个线程可以写入非原子变量,但多个线程从中读取. 会遇到问题吗?
- 提升精神 V2 Qi 语法线程安全吗?
- asio 链对象线程安全吗?
- 线程安全队列 c++
- 提供对不同类型的数据(建议、代码审查)的线程安全访问的类
- 如何以线程安全的方式更改目录?
- 线程安全的引用计数队列C++
- 析构函数和线程安全
- 适用于大型数组的无复制线程安全环形缓冲区