我有一些可以从多个线程访问的对象,需要同步。
我想要的解决方案涉及创建代理类,覆盖其operator->
,并锁定对operator->
的调用。这大概就是我想要的:
template <typename T>
class SynchronizedObject<T> {
lock_t l;
public:
??? operator->() {
lock(l);
// do the operation
unlock(l);
}
};
因此,我可以轻松地制作像SynchronizedObject<std::vector>
这样的同步向量,并且调用push_back
等同步。
但是,正如我已经做了一些研究,这并不完全是超载operator->
的工作原理,因为在我的示例中它需要返回T*
,并且只有在它返回后,才能生成致电push_back
或我感兴趣的任何方法。有没有什么方法可以实现我想要的,而不必访问宏观地狱?
答案 0 :(得分:2)
这是一个概念证明,它利用operator ->
的递归行为来透明地插入锁定代理。代理是不可移动的,不可分配的,因此无法意外存储(或者你真的必须意味着它)。
#include <iostream>
template <class T>
struct LockedPtr {
LockedPtr(T *_t) {
std::cout << "lock\n";
}
~LockedPtr() {
std::cout << "unlock\n";
}
LockedPtr(LockedPtr const &) = delete;
LockedPtr &operator = (LockedPtr const &) = delete;
T* operator -> () {
return _t;
}
private:
T *_t;
};
template <class T>
struct LockWrapper {
LockedPtr<T> operator -> () {
return {&_t};
}
private:
T _t;
};
struct DummyContainer {
void push_back(int i) {
std::cout << "push_back(" << i << ")\n";
}
};
int main() {
LockWrapper<DummyContainer> lv;
lv->push_back(1);
lv->push_back(2);
lv->push_back(3);
}
输出:
lock
push_back(1)
unlock
lock
push_back(2)
unlock
lock
push_back(3)
unlock