Resource Acquisition Is Initialization

C++ 的 RAII(Resource Acquisition Is Initialization)机制使用面向对象的特性可以容易地处理这个事情。RAII 其实使用 C++ 类的机制,在构造函数中分配资源,在析构函数中释放资源。下面看个例子。

std::mutex m;
 
void bad() 
{
    m.lock();                    // 请求互斥
    f();                         // 若f()抛异常,则互斥绝不被释放
    if(!everything_ok()) return; // 提早返回,互斥绝不被释放
    m.unlock();                  // 若bad()抵达此语句,互斥才被释放
}

  上面这个例子,在函数的第三条语句提前返回了,直接导致 m.unlock() 没有被调用,这样会引起死锁问题。我们来看一下用 RAII 的方式是怎样解决这个问题的。

//首先,先声明一个RAII类,注意其中的构造函数和析构函数
class LockGuard {
public:
  LockGuard(std::mutex &m):_m(m) { m.lock(); }
  ~LockGuard() { m. unlock(); }
private:
  std::mutex& _m;
}


//然后,我们来看一下,怎样使用的
void good()
{
  LockGuard lg(m);           // RAII类:构造时,互斥量请求加锁
  f();                             // 若f()抛异常,则释放互斥
  if(!everything_ok()) return;     // 提早返回,LockGuard析构时,互斥量被释放
}                                    // 若good()正常返回,则释放互斥

  

try {
  ... // 正常的业务代码
} catch (Exception1 e) {
  ... // 处理异常 Exception1 的代码
} catch (Exception2 e) {
  ... // 处理异常 Exception2 的代码
} finally {
  ... // 资源清理的代码
}

 

posted on 2020-05-14 21:10  KHacker  阅读(227)  评论(0编辑  收藏  举报