C++ で std::mutex を使ってスレッド間の排他制御2020年10月02日 12時29分17秒

C++11 からはスレッドのサポートが言語の一部になった。複数のスレッドを使って、作業を分割したりすると、排他制御が必要になってくる。std::mutex が使える。Mutex は mutual exclusion の略で、「お互い」に「干渉しあわない」といった意味になる。クリティカルセクションを作るのに使う。UNIX 等では、pthread と mutex はほぼ一体となっていた。複数のプログラムの流れが無いと排他制御する必要が無いので、まあ至極当然な流れとも言える。
% cat thread.cpp
#include <mutex>
#include <thread>
#include <iostream>

static std::mutex m;

void print()
{
    std::cout << "LOCKING" << std::endl;
    m.lock();
    std::this_thread::sleep_for( std::chrono::seconds( 3 ) );
    std::cout << "THREAD" << std::endl;
    m.unlock();
}

int main()
{
    std::thread t( print );

    std::this_thread::sleep_for( std::chrono::seconds( 1 ) );

    m.lock();
    std::cout << "MAIN" << std::endl;
    m.unlock();

    t.join();

    std::cout << "DONE" << std::endl;
}

メインスレッドは、スレッドを生成した後に一秒待機させている。そのため、子スレッドが先に mutex を取得する。子スレッドが三秒待機してからmutex を開放するので、メインスレッドが mutex を取得できるには、必ず子スレッドの後。そのため、THREAD が必ず MAIN よりも先に出力される。

コンパイルして実行した結果。スレッドライブラリを使うので -lptherad が必要になる。

% c++ -std=c++11 thread.cpp -lpthread
% ./a.out 
LOCKING
THREAD
MAIN
DONE

前回次回