「std::lock」の版間の差分
提供: C++入門
(ページの作成:「std::lock とは、C++のマルチスレッドプログラムで複数のmutexをロックするときにデッドロックを防ぐために、遅延ロック(defe...」) |
(相違点なし)
|
2013年12月29日 (日) 21:47時点における最新版
std::lock とは、C++のマルチスレッドプログラムで複数のmutexをロックするときにデッドロックを防ぐために、遅延ロック(deferred locking)を実現するために使用します。
読み方
- std::lock
- えすてぃーでぃー ろっく
概要
マルチスレッドプログラムで複数のmutexのロックが必要なケースがあります。このとき、ロックの順番を間違えると、デッドロックが発生します。デットロックとは、2つのスレッドが逆の順番にロックしようとしたとき、それぞれがもっているロックが解除されるのをお互いに待ち続けるような状況に陥ることです。
複数のロックをまとめて行うために、C++11では、std::lockで複数のmutexをまとめてロックする汎用の関数を提供しています。
複数のmutexをロックする例
ソースコード std_lock1.cpp
#include <iostream> #include <thread> #include <exception> #include <mutex> using namespace std; struct Mutex { std::mutex m; int i; Mutex(): i(0){} }; void do_worker1 (Mutex& m1, Mutex& m2) { std::cout << __PRETTY_FUNCTION__ << std::endl; //ここではロックしない std::unique_lock<std::mutex> ul1(m1.m, std::defer_lock); std::unique_lock<std::mutex> ul2(m2.m, std::defer_lock); //ここでロックする std::lock(ul1, ul2); std::cout << __PRETTY_FUNCTION__ << std::endl; m1.i++; m2.i++; // mutex unlocked ! } int main (int argc, char *argv[]) { try { Mutex m1,m2; std::thread t1(do_worker1, std::ref(m1), std::ref(m2) ); std::thread t2(do_worker1, std::ref(m1), std::ref(m2) ); t1.join(); t2.join(); } catch (std::exception &ex) { std::cerr << ex.what() << std::endl; } return (0); }
コンパイル
g++49 -std=c++11 -I/usr/local/lib/gcc49/include/c++/ \ -Wl,-rpath=/usr/local/lib/gcc49 -pthread std_lock1.cpp -o std_lock1
実行例
% ./std_lock1 void do_worker1(Mutex&, Mutex&)void do_worker1(Mutex&, Mutex&) void do_worker1(Mutex&, Mutex&) void do_worker1(Mutex&, Mutex&)
関連項目
mutexの種類 | 説明 |
---|---|
std::mutex | 非再帰的mutex |
std::recursive_mutex | 再帰的mutext |
std::timed_mutex | ロック関数でタイムアウトが可能な非再帰的mutex |
std::recursive_timed_mutex | ロック関数でタイムアウトが可能な再帰的mutex |
ロッククラステンプレート
関数 | 説明 |
---|---|
メンバ関数 | |
std::thread::thread | コンストラクタ。threadオブジェクトを作成します。 |
std::thread::~thread | スレッドがjoinかdetachされている必要があります。スレッドオブジェクトを破棄します。 |
std::thread::operator= | スレッドオブジェクトをmoveします。 |
オブザーバー | |
std::thread::joinable | スレッドが合流可能であるかチェックします。 |
std::thread::get_id | スレッドのIDを返します。 |
std::thread::native_handle | スレッドハンドルを返します。 |
std::thread::hardware_concurrency | 実装によってサポートされる同時スレッド数を返します。 |
操作 | |
std::thread::join | スレッドの終了を待ちます。 |
std::thread::detach | スレッドハンドルから独立して実行するスレッドを許可します。 |
std::thread::swap | スワップ |
非メンバ関数 | |
std::swap | スワップ |
カレントスレッドの管理 | |
std::this_thread::yield_id | 処理系に再スケジュールの機会を与えます。 |
std::this_thread::get_id | スレッドIDを返します。 |
std::this_thread::sleep_for | 指定した時間、現在のスレッドの実行を停止します。 |
std::this_thread::sleep_until | 指定した時刻まで、現在のスレッドの実行を停止します。 |