名前空間
変種
操作

std::scoped_lock

提供: cppreference.com
< cpp‎ | thread
 
 
スレッドサポートライブラリ
スレッド
(C++11)
(C++20)
(C++20)
this_thread 名前空間
(C++11)
(C++11)
(C++11)
相互排他
汎用ロック管理
(C++11)
scoped_lock
(C++17)
(C++11)
(C++11)
(C++11)(C++11)(C++11)
(C++11)
(C++11)
条件変数
(C++11)
セマフォ
ラッチとバリア
(C++20)
(C++20)
フューチャー
(C++11)
(C++11)
(C++11)
 
 
ヘッダ <mutex> で定義
template<class... MutexTypes>
class scoped_lock;
(C++17以上)

クラス scoped_lock はスコープ付きブロックの期間に対して1つまたは複数のミューテックスを所有するための便利な RAII スタイルの仕組みを提供するミューテックスラッパーです。

scoped_lock オブジェクトが作成されると、指定されたミューテックスの所有権の取得が試みられます。 scoped_lock オブジェクトが作成されたスコープから制御が離れると、 scoped_lock は破棄され、ミューテックスは逆順で解放されます。 複数のミューテックスが指定された場合、 std::lock を使用したかのようにデッドロック回避アルゴリズムが使用されます。

scoped_lock クラスはコピー可能ではありません。

目次

[編集]テンプレート引数

MutexTypes - ロックするミューテックスの型。 Lockable の要件を満たさなければなりません。 ただし sizeof...(MutexTypes)==1 の場合は BasicLockable を満たすだけで構いません

[編集]メンバ型

メンバ型 定義
mutex_type(if sizeof...(MutexTypes)==1) ミューテックス。 MutexTypes... の唯一の型

[編集]メンバ関数

scoped_lock を構築し、オプションで指定したミューテックスをロックします
(パブリックメンバ関数)[edit]
scoped_lock オブジェクトを破壊し、ミューテックスのロックを解除します
(パブリックメンバ関数)[edit]
operator=
[削除]
コピー代入可能ではありません
(パブリックメンバ関数)[edit]

[編集]

以下の例は RAII スタイルでデッドロックせずに2個のミューテックスをロックするため std::scoped_lock を使用します。

#include <mutex>#include <thread>#include <iostream>#include <vector>#include <functional>#include <chrono>#include <string>   struct Employee { Employee(std::string id): id(id){}std::string id;std::vector<std::string> lunch_partners;std::mutex m;std::string output()const{std::string ret ="Employee "+ id +" has lunch partners: ";for(constauto& partner : lunch_partners ) ret += partner +" ";return ret;}};   void send_mail(Employee &, Employee &){// simulate a time-consuming messaging operationstd::this_thread::sleep_for(std::chrono::seconds(1));}   void assign_lunch_partner(Employee &e1, Employee &e2){staticstd::mutex io_mutex;{std::lock_guard<std::mutex> lk(io_mutex);std::cout<< e1.id<<" and "<< e2.id<<" are waiting for locks"<<std::endl;}   {// use std::scoped_lock to acquire two locks without worrying about // other calls to assign_lunch_partner deadlocking us// and it also provides a convenient RAII-style mechanism   std::scoped_lock lock(e1.m, e2.m);   // Equivalent code 1 (using std::lock and std::lock_guard)// std::lock(e1.m, e2.m);// std::lock_guard<std::mutex> lk1(e1.m, std::adopt_lock);// std::lock_guard<std::mutex> lk2(e2.m, std::adopt_lock);   // Equivalent code 2 (if unique_locks are needed, e.g. for condition variables)// std::unique_lock<std::mutex> lk1(e1.m, std::defer_lock);// std::unique_lock<std::mutex> lk2(e2.m, std::defer_lock);// std::lock(lk1, lk2);{std::lock_guard<std::mutex> lk(io_mutex);std::cout<< e1.id<<" and "<< e2.id<<" got locks"<<std::endl;} e1.lunch_partners.push_back(e2.id); e2.lunch_partners.push_back(e1.id);}   send_mail(e1, e2); send_mail(e2, e1);}   int main(){ Employee alice("alice"), bob("bob"), christina("christina"), dave("dave");   // assign in parallel threads because mailing users about lunch assignments// takes a long timestd::vector<std::thread> threads; threads.emplace_back(assign_lunch_partner, std::ref(alice), std::ref(bob)); threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(bob)); threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(alice)); threads.emplace_back(assign_lunch_partner, std::ref(dave), std::ref(bob));   for(auto&thread : threads) thread.join();std::cout<< alice.output()<<'\n'<< bob.output()<<'\n'<< christina.output()<<'\n'<< dave.output()<<'\n';}

出力例:

alice and bob are waiting for locks alice and bob got locks christina and bob are waiting for locks christina and alice are waiting for locks dave and bob are waiting for locks dave and bob got locks christina and alice got locks christina and bob got locks Employee alice has lunch partners: bob christina Employee bob has lunch partners: alice dave christina Employee christina has lunch partners: alice bob Employee dave has lunch partners: bob

[編集] 欠陥報告

以下の動作変更欠陥報告は以前に発行された C++ 標準に遡って適用されました。

DR 適用先 発行時の動作 正しい動作
LWG 2981 C++17 scoped_lock<MutexTypes...> からの冗長な推定ガイドが提供されていました 削除されました

[編集]関連項目

ムーブ可能なミューテックスの所有権のラッパーを実装します
(クラステンプレート)[edit]
(C++11)
厳密なスコープベースのミューテックス所有権のラッパーを実装します
(クラステンプレート)[edit]
close