読者です 読者をやめる 読者になる 読者になる

recursive_mutexの実装

C++

cpprefjpでstd::recursive_mutexのリファレンスを書いていて実装が気になったので、Boost.Threadにあるrecursive_mutexの実装を見てました。
実装のポイントは以下の2点でした:
1. すでにロックされている場合、スレッドIDをチェックして同じだったら再度ロック処理はしない
2. 現在ロックが取得されているスレッドでの、ロックされている数をカウントし、0になったときにアンロックする


以下、std::mutexをベースにした簡易実装です:

#include <iostream>
#include <mutex>
#include <thread>
#include <boost/optional.hpp>

class recursive_mutex {
    std::mutex inner_mtx_;
    std::size_t lock_count_ = 0;
    boost::optional<std::thread::id> thread_id_;
public:
    void lock()
    {
        std::thread::id id = std::this_thread::get_id();
        if (lock_count_ == 0 || thread_id_.get() != id) {
            inner_mtx_.lock();
            thread_id_ = id;
        }
        ++lock_count_;
    }

    void unlock()
    {
        std::thread::id id = std::this_thread::get_id();
        if (thread_id_.get() != id)
            return;

        if (--lock_count_ == 0) {
            inner_mtx_.unlock();
            thread_id_ = boost::none;
        }
  }
};

int main()
{
    std::cout << "start" << std::endl;

    ::recursive_mutex mtx;
    mtx.lock();
    {
        mtx.lock();
        mtx.unlock();
    }
    mtx.unlock();

    std::cout << "end" << std::endl;
}
start
end

# 飽くまで実装イメージですので、本気実装がほしい方は標準やBoostのを使ってください。