ミューテックス(std::mutex)でlockする②

もくじ
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([&param]
        {
            func(1);
        });

    th_b = std::thread([&param] 
        {
            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

https://cpprefjp.github.io/reference/mutex/unique_lock.html