もくじ
https://tera1707.com/entry/2022/02/06/144447
やりたいこと
前回、std::mutexを使って、排他(C#のlock(obj)
的なこと)をやってみた。
が、下記ページによると、
https://cpprefjp.github.io/reference/mutex/mutex.html
このクラスのデストラクタは自動的に unlock() メンバ関数を呼び出すことはないため、通常このクラスのメンバ関数は直接は呼び出さず、 lock_guard や unique_lock といったロック管理クラスと併用する。
とのことで、通常は、単品(つまり前回記事のような使い方)では使わないらしい。
なので通常使うような使い方を試したい。
通常の使い方
std::lock_guard<std::mutex> lock(mtx);
でロックを取得する。
そこからスコープを抜けると、自動的にロックが解除される。
実験コード
#include <iostream> #include <thread> #include <mutex> static std::thread th_a; static std::thread th_b; std::mutex mtx; void func(int threadNo) { std::lock_guard<std::mutex> lock(mtx); // ロックを取得する ★肝はココ std::cout << "+ スレッド" << threadNo << "開始" << std::endl; for (size_t i = 0; i < 10; i++) { std::cout << " スレッドA実行中..." << i << std::endl; } std::cout << "- スレッド" << threadNo << "終了" << std::endl; // このスコープ抜けるときに、mutexを自動的にunlockしてくれる } int main() { int param = 0; th_a = std::thread([¶m] { func(1); }); th_b = std::thread([¶m] { func(2); }); // プログラム終了時にはjoinで終わるのを待つ th_a.join(); th_b.join(); }
そのほかの例(std::unique_lock)
もう少し高度な使い方をできるものもあるらしい。
std::unique_lock
https://cpprefjp.github.io/reference/mutex/unique_lock.html
※今回、自分がやりたいことをやるうえでは必要なさそう。
なので、いるときに調べる。
参考
std::lock_guard
https://cpprefjp.github.io/reference/mutex/lock_guard.html
std::unique_lock