C++でマルチスレッドと排他制御の基本の画像
芽萌丸プログラミング部 @programming
投稿日 2021/01/28

C++

C++でマルチスレッドと排他制御の基本

C++11から追加されている std::thread を利用し、C++でマルチスレッド処理を行う方法のメモです。

今回のサンプルは、あるカウンタ用の変数を2つのスレッドから共有しますが、排他制御して安全にカウントアップします。 変数の排他制御にはstd::mutexを利用します。

目次:

前提

  • Ubuntu 16.04 LTS
  • g++ 5.4.0

サンプルコード

thread.cpp

#include <iostream>
#include <mutex>
#include <thread>

using namespace std;

// 排他制御用ミューテックス
mutex mtx;
// スレッド間で共有する変数
int shared_count;

void count_thread() {
    for (int i = 0; i < 100000; ++i) {
        // shared_countを加算する前にミューテックスロックを取得
        lock_guard<mutex> lock(mtx);
        shared_count++; // 他スレッドからの変更がロックされます!
    }
}

int main() {
    // スレッド1を生成:
    thread t1(count_thread);
    // スレッド2を生成:
    thread t2(count_thread);

    cout << "before t1.join(). shared_count:" <<  to_string(shared_count) << endl;
    // スレッド1をjoin:
    t1.join();
    cout << "after t1.join(). shared_count:" << to_string(shared_count) << endl;

    cout << "before t2.join(). shared_count:" <<  to_string(shared_count) << endl;
    // スレッド2をjoin:
    t2.join();
    cout << "after t2.join(). shared_count:" << to_string(shared_count) << endl;
}

コンパイル&実行: (スレッドを使うために -pthread オプションを付けてコンパイルします)

## コンパイル:
$ g++ -o a.out thread.cpp -pthread -std=c++11

## 実行:
$ ./a.out

before t1.join(). shared_count:208
after t1.join(). shared_count:180733
before t2.join(). shared_count:181345
after t2.join(). shared_count:200000

最終的にカウンタは 100000 * 2 = 200000 で正しく終了していることがわかります。 (もしカウンタ更新の直前にlock_guard<mutex> lock(mtx);で排他制御しなかった場合、更新で衝突が発生し正しい数字になりません。)

以上です。

参考


芽萌丸プログラミング部
芽萌丸プログラミング部 @programming
プログラミング関連アカウント。Web標準技術を中心に書いていきます。フロントエンドからサーバサイドまで JavaScript だけで済ませたい人たちの集いです。記事は主に @TanakaSoftwareLab が担当。