C++14 共有ロック

N3659 Shared locking in C++ (Revision 2)


C++14では、新たにヘッダが追加され、multiple-readers / single-writerパターンをサポートするための、共有ロックの機能が入ります。
書き込みに比べて読み込みが多い場合に使用します。

shared_mutex mtx;
void reader()
{
    shared_lock<shared_mutex> lock(mtx); // mtx.lock_shared()が呼ばれる
    // ... 共有データからの読み込みアクセス ...

} // mtx.unlock_shared()が呼ばれる

void writer()
{
    lock_guard<shared_mutex> lock(mtx); // mtx.lock()が呼ばれる
    // ... 共有データへの書き込みアクセス ...

} // mtx.unlock()が呼ばれる

追加されるのは、以下の2つのクラスです。

// <shared_mutex>
namespace std {
  class shared_mutex;
  template <class Mutex> class shared_lock;
}

shared_mutexクラスは、2つのロックインタフェースを持ちます。

  • lock_shared()とunlock_shared()は、共有ロックのメンバ関数です。読み込みに使用します。
  • lock()とunlock()は、排他ロックのメンバ関数です。書き込みに使用しますが、こちらのインタフェースのみを使用する場合は、std::mutexと同じ読み込み/書き込みの効果を持ちます。


C++11からあるlock_guardクラスがコンストラクタとデストラクタでlock()/unlock()メンバ関数を自動的に呼んでくれるクラスだったのに対し、shared_lockクラスは、コンストラクタでlock_shared()、デストラクタでunlock_shared()を呼びます。
読み込みにはshared_lockを使用し、書き込みにはlock_guardを使用することになります。


※ reader <-> writer間の変換は、現状の仕様ではできないようです。Revision 1ではunlock_and_lock_shared()のようなインタフェースが提案されていましたが、C++14のドラフト仕様に導入されたRevision 2の仕様では、これがなくなっています。まだ練られていないということなのだと思います。