次の例では、複数のスレッドを使用するアプリケーションの例を示します。この例では、libC ライブラリの iostream オブジェクトを「MT-安全」で使用します。
このアプリケーションでは、スレッドを 255 個まで作成します。各スレッドはそれぞれ異なる入力ファイルから一度に 1 行ずつデータを読み込み、そのデータを出力ファイルに書き込みます。そのとき標準出力ストリーム cout を使用します。出力ファイルは全スレッドで共有するため、どのスレッドから出力されたかを示すタグを付けます。
// <ストリングデータ> は、任意の印刷可能文字
// タグは、整数値を char 型として書き込むため、
// 出力ファイルを表示するときは、次のように od を使用する必要がある
// od -c out.file |more
#include <stdlib.h>
#include <stdio.h>
#include <iostream.h>
#include <fstream.h>
#include <thread.h>
struct thread_args {
char* filename;
int thread_tag;
};
const int thread_bufsize = 256;
// 各スレッドのエントリルーチン
void* ThreadDuties(void* v) {
// 現スレッドの引数の取得
thread_args* tt = (thread_args*)v;
char ibuf[thread_bufsize];
// スレッドの入力ファイルをオープン
ifstream instr(tt->filename);
stream_locker lockout(cout, stream_locker::lock_defer);
while(1) {
// 一度に 1 行を読み込み
instr.getline(ibuf, thread_bufsize - 1, '¥n');
if(instr.eof())
break;
// 入出力操作を不可分命令的に実行するため、cout ストリームをロック
lockout.lock();
// データにタグを付けて cout に出力
cout << (unsigned char)tt->thread_tag << ibuf << "¥n";
lockout.unlock();
}
return 0;
}
main(int argc, char** argv) {
// argv: 1+ 各スレッドのファイル名リスト
if(argc < 2) {
cout << "usage: " << argv[0] << " <files..>¥n";
exit(1);
}
int num_threads = argc - 1;
int total_tags = 0;
// スレッド ID の配列
thread_t created_threads[thread_bufsize];
// スレッドのエントリルーチンへの引数の配列
thread_args thr_args[thread_bufsize];
int i;
for( i = 0; i < num_threads; i++) {
thr_args[i].filename = argv[1 + i];
// スレッドへのタグの割り当て − タグの値は 255 以下
thr_args[i].thread_tag = total_tags++;
// スレッドの生成
thr_create(0, 0, ThreadDuties, &thr_args[i],
THR_SUSPENDED, &created_threads[i]);
}
for(i = 0; i < num_threads; i++) {
thr_continue(created_threads[i]);
}
for(i = 0; i < num_threads; i++) {
thr_join(created_threads[i], 0, 0);
}
return 0;
}