概要
スレッドとは、プログラム上で複数の処理を並列に行うための仕組みです。
このプロジェクトでは、スレッドを使うために SDL をラップした hrk::Thread クラスを用意しています。
- hrk::Thread クラス
- 戻り値が int 型、引数が void* 型の関数を登録して実行できる。
- スレッドの動作を制御するために run(), stop(), wait() メソッドを提供する。
スレッド操作のイメージ
使い方
それでは、10 [msec] 毎に数値をインクリメントしながら表示するスレッドのサンプルを紹介します。
サンプルのソースコード
#include <iostream>
#include <SDL.h>
using namespace hrk;
using namespace std;
namespace
{
int number_output(void* arg)
{
int* first_value = reinterpret_cast<int*>(arg);
enum { Loop_times = 10 };
int value = *first_value;
for (int i = 0; i < Loop_times; ++i) {
cout << value << endl;
++value;
delay_msec(10);
}
return value;
}
}
int main(int argc, char *argv[])
{
static_cast<void>(argc);
static_cast<void>(argv);
int first_values[2] = { 0, 100 };
Thread thread_1st(number_output, &first_values[0]);
Thread thread_2nd(number_output, &first_values[1]);
thread_1st.run();
thread_2nd.run();
cout << "1st: last_value: " << thread_1st.wait() << endl;
cout << "2nd: last_value: " << thread_2nd.wait() << endl;
return 0;
}
実行した例
% ./thread_number_output
0
100
1
101
102
2
103
3
104
4
105
5
106
6
107
7
108
8
109
9
1st: last_value: 10
2nd: last_value: 110
この実行結果から、2つのスレッドの出力が混ざって表示されているのがわかります。
このサンプルではスレッドに渡す引数が1つなので問題ありませんが、複数の引数をスレッドに渡したい場合には、引数をまとめた構造体やクラスを作成して渡す必要があります。
typedef struct
{
int first_value;
int last_value;
} thread_args_t;
thread_args_t thread_args;
thread_args.first_value = 0;
thread_args.last_value = 16;
Thread thread(function, &thread_args);
スレッドは、複数タスクが同じリソースを操作することを可能にします。したがって、同じリソースについての排他制御が重要になってきます。
スレッドを使う際は、きちんとした設計が必要です。