Наличие объекта с обширным списком API.
Каков наилучший способ синхронизации этого объекта, т. Е. Объект уже существует в устаревшем коде и используется в сотнях строк кода.
Наивный способ - обернуть каждый вызов API к объекту std::mutex
. Есть ли более простой или элегантный способ сделать это?
Я попробовал приведенный ниже код, однако хотел бы узнать мнение об этом или альтернативные решения.
Ниже представлен класс-оболочка шаблона, который автоматически блокирует объект во время использования. то есть блокирует объект при создании и разблокирует при разрушении.
Этот шаблон очень похож на блокировку области, однако он полезен только для статических объектов / синглетонов, он не будет работать для разных экземпляров данного объекта
template <typename T> class Synced
{
static std::mutex _lock;
T& _value;
public:
Synced(T& val) : _value(val)
{
std::cout << "lock" << endl;
_lock.lock();
}
virtual ~Synced()
{
std::cout << "unlock" << endl;
_lock.unlock();
}
T& operator()()
{
return _value;
}
};
template <class T> std::mutex Synced<T>::_lock;
пример класса для использования с синхронизированным шаблоном класса
это может быть примером класса, упомянутого выше, с десятками API
class Board
{
public:
virtual ~Board() { cout << "Test dtor " << endl; }
void read() { cout << "read" << endl; }
void write() { cout << "write" << endl; }
void capture() { cout << "capture" << endl; }
};
пример использования, базовые вызовы, объект Synced не ограничен областью действия, поэтому деструктор вызывается сразу после точки с запятой
int main(int argc, char* argv[])
{
Board b;
Synced<Board>(t)().read();
cout <<" " << endl;
Synced<Board>(t)().write();
cout << " " << endl;
Synced<Board>(t)().capture();
cout << " " << endl;
return 1;
}
Здесь ниже вывод приведенного выше примера выполнения:
lock
read
unlock
lock
write
unlock
lock
capture
unlock
Test dtor