共有ロック


概要

C++11ではマルチスレッドサポートにより、基本的な排他制御機能が追加された。 C++14では、これに加え所謂readers writer lockパターンを実現するshared_lock, shared_time_mutexが追加されている。

※ タイムアウトなしのshared_mutexは、C++14の策定に間に合わず、C++17での採用に見送られた。

共有Mutexには、同じ共有Mutexに対して複数の実行スレッドが同時に取得可能な共有所有権(共有ロック)と、ただ一つの実行スレッドのみ取得可能な排他所有権(排他ロック)があり、 排他ロックは通常のロックと同様に、他の実行スレッドが共有、排他含め一つの実行スレッドのみがロックを取得可能となる。

共有ロックを行うためのヘルパクラスとして、shared_lockクラスがある。 これは、lock_guradクラスと同様にコンストラクタで共有ロックを取得し、デストラクタでロックを解放する動作を実現する。 排他ロックを行う場合は、shared_time_mutexに対してlock_guradを使用すれば良い。

shared_time_mutex, shared_lockを使用する場合は、ヘッダファイルshared_mutexをインクルードする。

以下にサンプルを示す。

#include <mutex>
#include <shared_mutex>
#include <thread>
#include <iostream>

std::shared_timed_mutex m;
std::mutex cout_m;
void print(const std::string& msg) {
    std::lock_guard<std::mutex> lock(cout_m);
    std::cout << msg << std::endl;
}

void writer(void) {
    using namespace std::literals::chrono_literals;
    {
        std::lock_guard<std::shared_timed_mutex> lock(m);
        print("writer: exclusive lock get.");
        std::this_thread::sleep_for(1s);
        print("writer: exclusive lock release.");
    }
    std::this_thread::sleep_for(2s);
    {
        std::lock_guard<std::shared_timed_mutex> lock(m);
        print("writer: exclusive lock get.");
        std::this_thread::sleep_for(1s);
        print("writer: exclusive lock release.");
    }
}

void reader(void) {
    using namespace std::literals::chrono_literals;
    std::this_thread::sleep_for(100ms);
    {
        std::shared_lock<std::shared_timed_mutex> lock(m);
        print("reader: shared lock get.");
        std::this_thread::sleep_for(1s);
        print("reader: shared lock release.");
    }
    {
        std::shared_lock<std::shared_timed_mutex> lock(m);
        print("reader: shared lock get.");
        std::this_thread::sleep_for(2s);
        print("reader: shared lock release.");
    }
}

int main() {
    std::thread t1(writer);
    std::thread t2(reader);
    std::thread t3(reader);

    t1.join();
    t2.join();
    t3.join();
    return 0;
}

上記のプログラムを実行した際の出力例を以下に示す。

writer: exclusive lock get.
writer: exclusive lock release.
reader: shared lock get.
reader: shared lock get.
reader: shared lock release.
reader: shared lock get.
reader: shared lock release.
reader: shared lock get.
reader: shared lock release.
reader: shared lock release.
writer: exclusive lock get.
writer: exclusive lock release.

results matching ""

    No results matching ""