##スリープする

std::this_thread という名前空間(!)からカレントスレッドを操作することができて、 this_thread::sleep_for を呼ぶとスレッドを一定時間休ませることができます。sleep_for が取る引数の型は chrono::duration というテンプレートクラスの値になります。

template <class Rep, class Period = ratio<1> >
class duration;

なにやら難しげですが、同じ chrono 名前空間に hours, minutes, seconds など、単位を表す型が実体化されて typedef されていますので、これらのコンストラクタに整数を入れれば大丈夫。

例えば1秒間眠りたいときは

this_thread::sleep_for(chrono::seconds(1))

とやります。何気にポータブルに sleep する方法が今までなかったのでシングルスレッドでも使えそうですね。

##スレッドを生成する

スレッドを作る時は、コンパイラにオプションを渡してマルチスレッドプログラムであることを伝える必要があるかもしれません。g++ なら -pthread を指定する必要があります。

thread 型のオブジェクトを作ればもうスレッドが出来て走りだします。コンストラクタへの引数は処理内容を表す関数と、その関数へ渡す引数(いくつでも)。

生成したスレッドに合流したい時は、オブジェクトの join メンバー関数を呼び出します。というか join しないで終了するとエラーになりました。

void proc(int n)
{
    cout << "わたしは" << n << "円です。\n";
}

int main()
{
    thread t1(proc, 10);

    t1.join();
}

エントリーポイントの関数は関数オブジェクトやラムダでも大丈夫です。

##スリープソートを書いてみる

やっぱり役に立つプログラムを書かなきゃね (ゝω・)v ってことで、スリープソートと呼ばれる巧妙なアルゴリズムを使って、コマンドラインから渡された整数を昇順に並べかえるプログラムを書きます。

#include <iostream>
#include <thread>
#include <chrono>
#include <vector>
#include <cstdlib>

using namespace std;

void sleep_and_print(int n)
{
    this_thread::sleep_for(chrono::seconds(n));
    cout << n << endl;
}

int main(int argc, char *argv[])
{
    vector<shared_ptr<thread> > slaves;

    for (int i = 1; i < argc; i++)
    {
	int n = atoi(argv[i]);
	shared_ptr<thread> t( new thread(sleep_and_print,n) );

	slaves.push_back(t);
    }

    for (auto t : slaves)
	t->join();
}

thread 型はコピーできないのでポインターを使いました。

$ time ./a.out 14 2 9 4
2
4
9
14

real	0m14.005s
user	0m0.006s
sys	0m0.000s

やったね (ゝω・)v