具有具有广泛API列表的对象。
同步该对象的最佳方法是什么,即该对象已经存在于旧版代码中,并且已在数百行代码中使用。
天真的方法是使用std::mutex
将每个API调用包装到对象。有没有更简单或更优雅的方法呢?
我尝试使用下面的代码,但是想征询它的意见或其他解决方案。
下面是模板包装器类,它在使用过程中自动锁定对象。即在创建对象时将其锁定,在破坏对象时将其解锁。
此模式与作用域锁定非常相似,但是它仅对静态对象/单例有用,不适用于给定对象的不同实例
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
答案 0 :(得分:0)
仅当我控制所有可能的错误条件时,我才将互斥锁用于非常小的关键部分,可能只需要几行代码。对于复杂的API,您可能最终使/互斥锁处于意外状态。我倾向于使用reactor pattern解决这类问题。是否可行取决于您是否可以对此对象合理地使用序列化/反序列化。如果您必须自己编写序列化,请考虑诸如API稳定性和复杂性之类的事情。我个人更喜欢zeromq,因为这种东西在实际中使用时,您的行程可能会有所不同。