Есть ли способ создать этот «статический класс»? так что это потокобезопасно?

У меня есть класс со всеми статическими методами, как это:

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;
...
}

3

Решение

Вы можете сохранить оригинальный макет класса Aили даже вместо этого измените его на пространство имен, но вам придется определить GlobalData struct как локальное хранилище потока, если содержащиеся в нем данные должны быть специфическими для каждого потока:

 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() { /* ... */ }
}

что улучшает читабельность вашего кода.

Это же правило должно применяться к любому фрагменту данных глобальной области видимости в вашем исходном коде, который должен стать специфичным для потока.

2

Другие решения

Лучше было бы не использовать A в статической реализации вообще. Это будет означать, что вы создаете экземпляр A и используете его в клиентском коде посредством внедрения зависимостей.

Затем вы можете реализовать доступ RW к данным A, используя стандартные примитивы синхронизации.

Поскольку ваш A имеет статическое состояние, а A не является внедренной зависимостью, код, использующий A внутри, будет синхронизироваться с примитивами синхронизации, которые вы хотите добавить в реализацию A. Это вводит потенциальные взаимоблокировки, которые полностью невидимы из клиентского кода, которые может быть трудно найти и диагностировать (в зависимости от сложности взаимодействий клиентского кода A).

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector