やんちょふのブログ

ご連絡はTwitterアカウント@syoyuu616にて受け付けております

C++学習記録 スレッド 編1

大学に入学しました。やんちょふです。

しばらくPythonで数値処理ばかりしており、C++の勉強をさぼっていましたので、学習を開始しました。学習メモを不定期で更新したいと思います。

今回はスレッドです。C++11から追加された、マルチスレッドを扱うライブラリの使い方を試してみました。以下コードです。

#include <iostream>
#include <future>
#include <thread>

void Wait(int c) {
  std::this_thread::sleep_for(std::chrono::seconds(c));
}

int main() {
  std::vector<std::thread> threads;
  std::chrono::system_clock::time_point start, end;

  //multi thread
  start = std::chrono::system_clock::now();
  for (int i = 0; i < 3; i++) {
    threads.push_back(std::thread([] { Wait(3); }));
  }
  for (auto &th : threads) {
    th.join();
  }
  end = std::chrono::system_clock::now();
  double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
  std::cout << "multi: " << elapsed << std::endl;

  //single thread
  start = std::chrono::system_clock::now();
  for (int i = 0; i < 3; i++) {
    Wait(3);
  }
  end = std::chrono::system_clock::now();
  elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
  std::cout << "single: " << elapsed << std::endl;

  return 0;
}

3つのスレッドでそれぞれ3秒待たせた場合と、一つのスレッドで3秒を3回分待たせるプログラムです。これを実行すると結果は次のように出力されました。

multi: 3003
single: 9040

並列に処理が行われていることが確認できました。

以上のようにしてマルチスレッドを書くことができましたが、ソースコードの説明をざっくりとします。

まず次のコードです。

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

関数名そのままですが、指定した秒数待機させるコードです。chronoは時間に関するヘッダです。上記のソースコードでは単位として秒を指定しており、またmain関数内ではミリ秒を指定しています。このほかにマイクロ秒(microseconds)、分(minutes)、時間(hours)が指定できます。

this_thread名前空間は現在のスレッドに関する情報にアクセスするグループとなっています。今回使用したsleep_for関数以外にsleep_until関数などがあります。

main関数内では処理開始前と開始後とで以下のコードを記述しています。

 start = std::chrono::system_clock::now();
//何らかの処理
 end = std::chrono::system_clock::now();
double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();

duration_cast関数は入力した値を、指定した時間単位に変換します。もとの値よりも分解能が小さい単位にしか変換できない点が注意です。(Wait関数ではミリ秒単位にすればよかったと思いましたが動きがわかったのでこれで良しとします)

今回は以上です。

実行環境
OS : Windows10
コンパイラ : mingw gcc 7.3.0