マルチスレッドプログラミング
マルチスレッドプログラミング (multi thread programming)とは、並列に処理を実行するためのプログラミングで、マルチスレッドによってプログラムのパフォーマンスを改善できます。
読み方
- マルチスレッドプログラミング
- まるちすれっどぷろぐらみんぐ
- multi thread programming
- まるちすれっどぷろぐらみんぐ
目次
概要
マルチスレッドを使わずにC++でプログラムを書くと、上から下へプログラムが実行されます。並列に実行されないため、1行目が命令が終了するまで、次の行の処理ははじまりません。これは、シングルプロセス、シングルスレッドのプログラムと言われます。
プロセスは、1つ以上のスレッドを持ちます。「複数のスレッドを持つこと」をマルチスレッドを呼びます。
スレッドとは、プログラムの実行単位です。複数のスレッドを持つことで、処理Aと処理Bが同時に行えるようになります。複数のサーバに問い合わせを行うプログラムが、サーバAとサーバBに順番に問い合わせを行うよりも、たいていの場合は、同時(並列)に問い合わせを行うほうが、プログラムの実行時間は、短くなります。
マルチスレッドとマルチプロセスの違い
マルチスレッドプログラムとマルチプロセスには、いくつかの違いがあります。
- 1つのプロセスか、複数のプロセスか
- メモリ空間が共有かどうか
マルチスレッドのプログラムは、1つのスレッドでコアダンプすると、プロセスが落ちるので、ほかのスレッドも道連れになります。マルチプロセスのプログラムは、プログラムでコアダンプしても(プログラムが強制終了しても) 、ほかのプロセスには影響がありません。
マルチスレッドは、シングルプロセスであるため、すべてのスレッドが同じメモリ空間にアクセスできます。そのため、ロックなどの処理が必要になります。 マルチプロセスの場合、プロセスごとに違うメモリ空間にマッピングされるため、データの共有は、プロセス間通信が必要になります。しかしながら、メモリのアクセスにロックなどの処理が不要です。
マルチプロセスプログラミングに比べ、マルチスレッドプログラミングのほうが、より高度なプログラミングスキルを要求されます。プログラムのデバッグも非常に難しくなります。
マルチスレッドとマルチコア
マルチスレッドのプログラムは、マルチコアCPUの環境で実行したほうが、スループットが上がります。非マルチスレッドなプログラム(シングルスレッド)は、マルチコア環境であっても、1つのコアしか利用できないため、1コア分のスループットしか出せません。
マルチスレッドプログラミングをするには
マルチスレッド/並列コンピューティングが進化しています。
マルチスレッドプログラミングをするには、以前は、pthread を利用されていました。その後、C++では、std::thread(boost::thread)などのスレッドライブラリが開発されました。
さらに C++11では、std::promise や std::asyncなどの非同期実行するための機能が提供されました。
OpenMP, Cilk Plus, OpenACC などにより、並列コンピューティングがより簡単になりました。プログラムにプリプロセッサディレクティブを用いて、プログラムを注釈することで、並列実行が可能になります。
pthreadは、非常に原始的です。新しいコンパイラが利用できるのであれば、std::threadや非同期実行の機能、もしくは、並列コンピューティングの機能を利用するのが良いでしょう。
マルチスレッドとコンパイラ
並列コンピューティング、マルチスレッド、非同期処理の最新の機能を利用するには、最新のC++コンパイラを利用しなければならないケースがあります。
関連項目
非同期処理のテンプレート
std::thread
関数 | 説明 |
---|---|
メンバ関数 | |
std::thread::thread | コンストラクタ。threadオブジェクトを作成します。 |
std::thread::~thread | スレッドがjoinかdetachされている必要があります。スレッドオブジェクトを破棄します。 |
std::thread::operator= | スレッドオブジェクトをmoveします。 |
オブザーバー | |
std::thread::joinable | スレッドが合流可能であるかチェックします。 |
std::thread::get_id | スレッドのIDを返します。 |
std::thread::native_handle | スレッドハンドルを返します。 |
std::thread::hardware_concurrency | 実装によってサポートされる同時スレッド数を返します。 |
操作 | |
std::thread::join | スレッドの終了を待ちます。 |
std::thread::detach | スレッドハンドルから独立して実行するスレッドを許可します。 |
std::thread::swap | スワップ |
非メンバ関数 | |
std::swap | スワップ |
カレントスレッドの管理 | |
std::this_thread::yield_id | 処理系に再スケジュールの機会を与えます。 |
std::this_thread::get_id | スレッドIDを返します。 |
std::this_thread::sleep_for | 指定した時間、現在のスレッドの実行を停止します。 |
std::this_thread::sleep_until | 指定した時刻まで、現在のスレッドの実行を停止します。 |
mutex
mutexの種類 | 説明 |
---|---|
std::mutex | 非再帰的mutex |
std::recursive_mutex | 再帰的mutext |
std::timed_mutex | ロック関数でタイムアウトが可能な非再帰的mutex |
std::recursive_timed_mutex | ロック関数でタイムアウトが可能な再帰的mutex |
ロッククラステンプレート
並列コンピューティング
ツイート