优雅的 mutex on/off 功能开关?

Elegant mutex on/off switch for functions?

您能想出一种优雅的方法来使用可选的互斥锁创建(成员)函数吗?出于显而易见的原因,让我们忽略宏。

当然,最简单的方法是使用两个函数:

int getIndex() const    { std::lock_guard m( mtx ); return nm_getIndex(); }
int nm_getIndex() const { return _index; }

这会创建高效的代码,但它依赖于代码重复。基本上,您最终会得到大多数函数声明两次。

另一种方法是将它们变成模板函数。布尔模板参数将用作 "en-/disabler"。然后你可以像这样调用函数:

auto index = getIndex< NoMutex >();

每当在内部使用函数时(否则锁定互斥体)。这里的问题是确保即使抛出异常也能解锁互斥量。也就是说,您不能简单地使用

if constexpr( MutexOn == true ) {
    mutex.lock();
}
do some stuff;
if constexpr( MutexOn == true ) {
    mutex.unlock();
}

我目前唯一能想到的就是围绕互斥量构建一个 class 并将其放入联合体中。 class 然后可以 "play the lock_guard" 或什么都不做。虽然我很确定这会在发布代码中得到适当优化,但它看起来仍然很麻烦且不灵活。 因此,不知道你能不能想出更好的办法?

谢谢!

我能想到的最简单的方法是:

  1. 创建一个 noop lock_guard class.

  2. 创建一个始终使用指定为模板参数类型的锁守卫的模板函数。

  3. 当你想要一个 non/blocking 版本的函数时,你可以传入 noop guard

例如:

template<typename Guard>
int getIndex<Guard>() const    { Guard m( lock ); return nm_getIndex(); }

class NoopLockGuard ; //dummy class. it does absolutely nothing
int i = getIndex<NoopLockGuard>()
int j = getIndex<std::lock_guard>()

编译器应该能够使用 NoopLockGuard 优化版本,这样它会导致最小或零性能损失。