44

我将使用boost::mutexfrom boost/thread/mutex.hpp。有几种方法可以锁定/解锁互斥锁:with scoped_lock, unique_lock, lock_guard, mutex 的成员函数::lock()and::unlock()和非成员函数lock()and unlock()

我注意到,这boost::scoped_mutex是使用互斥锁的最流行的方式之一。为什么它比成员函数更::lock()可取::unlock()

特别是,我为什么要使用

{
  boost::scoped_lock lock(mutex)
  // ...
  // read/output sharing memory.
  // ...
}

而不是

mutex.lock()
// ...
// read/output sharing memory.
// ...
mutex.unlock()

仅仅scoped_lock因为某些样式编码的观点而更好还是::lock()/::unlock()“线程足够安全”?

4

2 回答 2

76

为什么比成员函数 ::lock() 和 ::unlock() 更可取?

与RAII 习语普遍流行的原因相同(这只是其无数实例之一):因为您可以确定在不解锁互斥锁的情况下不会离开当前范围。

请注意,这不仅仅是忘记调用unlock():当您的互斥锁被锁定时可能会发生异常,并且您的调用可能永远无法到达,即使您的调用和调用之间unlock()没有任何return语句。lock()unlock()

m.lock() // m is a mutex
// ...
foo(); // If this throws, your mutex won't get unlocked
// ...
m.unlock()

在这种情况下,你的守卫的析构函数scoped_lock将在堆栈展开期间被调用,确保相关联的互斥锁总是被释放。

{
    boost::scoped_lock lock(m); // m is a mutex
    // ...
    foo(); // If this throws, your RAII wrapper will unlock the mutex
    // ...
}

此外,在许多情况下,这将提高代码的可读性,因为您不必unlock()在每个return语句之前添加调用。

于 2013-03-02T21:21:37.903 回答
7

您可以使用

std::lock_guard<std::mutex> lock(mutex);

如果不想使用 boost 库。

于 2016-04-26T14:21:31.457 回答