共有ロック
概要
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.