std::unique_lock<T>
定义了一个移动构造函数,可以随意使用,但这种方法本身并不是非常成功。 您应该检查您的锁定粒度,通常如果您无法提供内部同步并要求用户在对某个对象执行操作(或需要执行多个操作时)时保持锁定状态,则没有理由将该互斥锁存储在目的。
如果我不得不店内对象互斥,我会用一些包装,让我做到以下几点:
locking_wrapper<Test> test;
test.do_locked([] (Test & instance) {
/* The following code is guaranteed not to interleave with
* any operations performed on instance from other threads. */
// your code using instance here
});
的locking_wrapper<T>
将存储存储内的对象的实例,并提供一个参考它同时保持对内部互斥锁的锁定。依靠编译器内联代码的能力,这种方法不应该超出你想要解决的问题。
上实现locking_wrapper
总体思路如下:
template<typename T>
class locking_wrapper
{
mutable std::mutex mutex;
// the object which requires external synchronization on access
T instance;
public:
/* Here we define whatever constructors required to construct the
* locking_wrapper (e.g. value-initialize the instance, take an
* instance passed by user or something different) */
locking_wrapper() = default;
locking_wrapper(const T & instance) : instance{instance} {}
// Takes a functor to be performed on instance while maintaining lock
template<typename Functor>
void do_locked(Functor && f) const {
const std::lock_guard<std::mutex> lock{mutex};
f(instance);
}
};
您可以调用任何实体传递给do_locked
,你认为合适,但是是lambda表达式调用它就像我先前建议将给它最好的机会,而不用任何开销。
请注意,使用这种方法与引用,可移动对象或其他类型,我还没有预见将需要对代码进行一些修改。
使用'unique_lock'代替? –
如果我用'lock_guard'替换'lock_guard',我会得到我需要的吗? – Ufx
如果对象只是从外部锁定,而不是从内部锁定,为什么互斥体需要在内部声明? –