优雅的 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" 或什么都不做。虽然我很确定这会在发布代码中得到适当优化,但它看起来仍然很麻烦且不灵活。
因此,不知道你能不能想出更好的办法?
谢谢!
我能想到的最简单的方法是:
创建一个 noop lock_guard class.
创建一个始终使用指定为模板参数类型的锁守卫的模板函数。
当你想要一个 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
优化版本,这样它会导致最小或零性能损失。
您能想出一种优雅的方法来使用可选的互斥锁创建(成员)函数吗?出于显而易见的原因,让我们忽略宏。
当然,最简单的方法是使用两个函数:
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" 或什么都不做。虽然我很确定这会在发布代码中得到适当优化,但它看起来仍然很麻烦且不灵活。 因此,不知道你能不能想出更好的办法?
谢谢!
我能想到的最简单的方法是:
创建一个 noop lock_guard class.
创建一个始终使用指定为模板参数类型的锁守卫的模板函数。
当你想要一个 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
优化版本,这样它会导致最小或零性能损失。