std::threadつかってみる

std::threadの使い方メモ。
まずは基本から。

#include <iostream>
#include <thread>
using namespace std;

class Hoge{
public:
  Hoge() : m_count(0){/**/}

  void operator()(){
    for(int i=0; i<10000000; ++i){
      m_count++;
    }
  }

  int m_count;
};


int main(int argc, char **argv){
  Hoge hoge;
  thread tr(ref(hoge));
  tr.join();

  cout << hoge.m_count << endl;

  return 0;
}

処理としては別スレッドでカウントアップさせてるだけ。


operator()を実装してるオブジェクトをstd::threadに渡してあげると、スレッドが走る。終了待つときはjoin()使う。
オブジェクトのコピーを発生させたくないときは、上の例のようにref(hoge)ってやる。なので、オブジェクトコピーされてもいい場合はthread tr(hoge);でもおk。今回は最後に結果表示したかったので、ref使ってみました。


このプログラムのmainを

int main(int argc, char **argv){
  Hoge hoge;
  thread tr1(ref(hoge));
  thread tr2(ref(hoge));

  tr1.join();
  tr2.join();

  cout << hoge.m_count << endl;

  return 0;
}

ってやっちゃうと、カウンタ変数m_countがスレッド間で共有されてるので、きっちりとした値が出てきません。
えぇい!mutexだ!mutexをよこせ!!
ということでstd::mutex使ってみる。


mutex使う版

#include <iostream>
#include <thread>
#include <mutex>
using namespace std;

class Hoge{
public:
  Hoge() : m_count(0){/**/}

  void operator()(){
    for(int i=0; i<10000000; ++i){
      lock_guard<mutex> lock(m_countMutex);
      m_count++;
    }
  }

  int m_count;
  mutex m_countMutex;
};


int main(int argc, char **argv){
  Hoge hoge;
  thread tr1(ref(hoge));
  thread tr2(ref(hoge));

  tr1.join();
  tr2.join();

  cout << hoge.m_count << endl;

  return 0;
}

lock_guard lock(m_countMutex);ってやってるところでmutexをロックしてます。
アンロックしとらんじゃないかー!!って、思うかもしれないけど、lock_guardの変数の寿命が切れたときにアンロックされるので大丈夫です。
これで、20000000まできちんとカウントアップされるはずです。(´・∀・`)ヘー


なんか間違ってたらごめん