11新しいC ++標準、マルチスレッドの概念の導入のための公用語。新基準は、マルチスレッドC ++プログラムを管理するためのスレッド・オブジェクトを作成することで、スレッドライブラリのスレッドを提供します。
本論文では、簡単に関連する概念とスレッドのいくつかの基本的なC ++マルチスレッド使用法について話しています。
並列に実行0
並列実行のために必要な2つの条件:
- マルチプロセッサ(複数のプロセッサ)又はマルチコアプロセッサ(マルチコアプロセッサ)
- 並列ソフトウェア
ソフトウェアの並行実行とは、2つのカテゴリに分けることができます。
- マルチスレッド(プロセスと並行して複数のスレッド)。
- より複雑な処理(並列で異なるプロセス)。
マルチスレッドの場合、主な関心事は、スレッドセーフのためのスレッド間の措置を同期しています。
マルチプロセスのために、主な関心事は、プロセス間のメッセージおよびデータを渡すために使用されるプロセス間通信機構です。
C ++標準では唯一のプラットフォーム固有のAPIに依存することができ、複数のプロセス間の通信のための関連規格ではありませんので。この記事では、マルチスレッド関連に焦点を当てています。
1. C ++マルチスレッドプラットフォーム
11、窓およびLinuxプラットフォームの前にC ++は、それぞれ、自分のマルチスレッドの基準を持っています。C ++で記述された複数のスレッドを使用すると、多くの場合、特定のプラットフォームに関連付けられています。
- 作成および管理マルチスレッドのWin32 APIのウィンドウプラットフォーム。
- Linuxでは、あるマルチスレッドAPIのPOSIX標準は、スレッドやPthreadsのライブラリは、クラスは、UNIX上で実行することができます提供します。
新しいC ++ 11標準では、あなたは、単にHREADライブラリを使用して複数のスレッドを管理することができます。スレッドライブラリは、異なるプラットフォーム、マルチスレッドのAPIのラッパーとして見ることができます。
そのため、新しい標準ライブラリを使用するプログラムは、クロスプラットフォームで書かれて提供します。
C ++ 11スレッド或2のpthread
pthreadsのは、ライブラリはLinuxでC ++でのスレッドはスレッドの基本的な操作の賛成で、操作に関連するいくつかのスレッドを提供し、より直接的で便利です。
#include <pthread.hの>
のpthread_create(スレッド、ATTR、start_routineが、引数)
Linuxのpthread pthreadライブラリを接続する必要があるため(編集者は、いくつかの-std = C ++ 11を必要とするかもしれません)。
G ++ source.cpp -lpthread -o source.o
スレッド内Tucao 11の新しい標準のC ++クラスのための多くのオンラインがありますが、最初のC ++標準スレッドライブラリとして、そのようなクロスプラットフォームとして認識の価値があるいくつかの地域では、使いやすいがありますが。
そして、新しい標準を簡単に管理のロックを達成するためにRAIIを使用することができます。
あなたはマルチスレッドでの綿密な外観をしたい場合は、そのpthreadのは良い選択です。あなたは細部にあまり注意せずにクロスプラットフォームやマルチスレッドのいくつかの簡単なシーンを実現したい場合は、標準ライブラリのスレッドの権限が最良の選択です。
要するに何も良いか悪いかのポイントがありません、それはうまく収まります。あなたは見つけることができた場合は、すべてのことができます。本論文では、後者について説明します。
最初の練習の理論の後に3
マルチスレッド関連の学習のために、概念のいくつかは、明確なスレッド関連も、非常に重要です。
このようなスレッドは、そのようなシステムのプロセスと通信する方法を相互に排他的な関係を持つスレッドセーフ、スレッド同期関係として。
そうでなければ、実際の書き込みマルチスレッドプログラムは、次のような、あまりにも多くの問題、に実行されます。
- デッドロック、応答がありません。
- 結果は期待を満たしていません。
- マルチスレッド性能がそれほど向上しません。
- 混乱プログラム実行プロセス;
- 私はデバッグする方法がわかりません。
- 良い時と悪いプログラムの実行。
光セーフ、これらだけではデバッガが、推測した結果によると、現実的ではないことを理解するために多くの理論があります。
スレッドの概念に関連についてボーエンネジ山のPythonを紹介するために、私の前の例を参照することができます。
例4スレッドのマルチスレッド
マルチスレッドCを作成するために、例++ 11標準ライブラリのスレッドを見てください:
1の#include <iostreamの> 2の#include <スレッド> 3の#include < ストリング > 4 5 使用 名前空間STDを、 6 7 INTの TSTART(CONST 文字列&TNAME){ 8 COUT << " スレッドテスト!" << TNAME << ENDL。 9 リターン 0 ; 10 } 11 12 INT メイン(){ 13 、スレッドT(TSTART、" C ++ 11スレッド!" )。 14 t.join(); 15 裁判所未満<< " 主な機能!" << てendl; 16 }
生成スレッドを管理するためのスレッドを使用して、標準ライブラリオブジェクトをマルチスレッド。この例では、tは新しいスレッドオブジェクトのスレッドを示します。
スレッドを作成するには、4.1標準ライブラリの方法
オープンスレッドヘッダファイル、あなたは明らかに提供コンストラクタスレッドを見ることができます。
- デフォルトのコンストラクタスレッド(noexcept)。
- パラメータテンプレートコンストラクタ関数を受信し、渡す<クラス_Fn、クラス... _Args、...>明示的なスレッド(_Fn && _Fx、_Args && ... _Ax)
- 移動构造函数スレッド(スレッド&& _Other)noexcept。
- コピーコンストラクタスレッド(定数スレッド&)=削除します。
- 代入演算子コピースレッド&演算子=(CONSTスレッド&)=削除します。
前記コピーコンストラクタと代入演算子のコピーをコピーして別のスレッドオブジェクトに割り当てることができないのstd ::スレッドオブジェクトを意味し、無効になっています。
デフォルトコンストラクタは空のスレッドオブジェクトを構築しますが、任意のスレッドを表すものではありません。
コンストラクタは、スレッドオブジェクトを作成し、スレッドがオブジェクトの着信機能が参加可能であるから実行を開始するパラメータを受け取り、
ムーブコンストラクタは、他のスレッドオブジェクトにスレッドオブジェクト制御権限スレッドと見なすことができ、実行された後、着信スレッドオブジェクトは、任意のスレッドを表していません。
INT のmain() { int型のarg = 0 。 std ::スレッドT1; // t1はスレッド表現されていない のstd ::スレッドT2(関数func1、引数+ 1)。 // 値によってスレッドに渡す のstd ::スレッドT3(関数func2、STD :: REF(引数))。 // 参照して、スレッドに渡す のstd ::スレッドT4(STD ::移動(T3))。 // T4は今)(func2のを実行しています。t3はもはやスレッドではありません // t1.join()エラー! t2.join(); // t3.join()エラー! t4.join(); }
ほとんどの場合、それは我々が使用する方法上述した第2のスレッドを作成することです。参加し、切り離しで次の一見。
4.2参加&&外します
スレッドの作成のために、一般的には、その破壊の前に参加し、切り離し関数を呼び出します。
これは、呼び出し元のスレッドの状態が非常に重要であるだけでなく、前と後に、これら2つの関数のタイミングと意義を把握するために呼び出します。
- ターゲットスレッドが終了するまで現在のスレッドがブロックされます参加。
- 唯一のアクティブなスレッドは、連結可能による缶()関数をチェックし、参加呼び出すことができます。
- 真連結可能()==は、現在のスレッドがアクティブなスレッドが参加機能を呼び出すことができるであることを示しています。
- デフォルトコンストラクタは、オブジェクトがfalse()==結合可能で作成されます。
- 参加合流可能が偽になります後にのみ、一度呼び出され、それは、スレッドが終了したことを示しています。
- コールternimate()スレッドは== false)を(結合可能でなければなりません。
- スレッドが真==)(結合可能であるスレッドでの活動が終了した場合でも、()関数を呼び出して参加していない場合でも、参加()関数を呼び出すことができます。
- スレッドオブジェクトを切り離し、糸分離によって表されます。
- スレッドを表現し、それが完全に分離を表しスレッドオブジェクトを切り離す呼び出します。
- スレッドの分離が制約と規制されていないされた後、それが完成し、リリースリソースまで、デーモンスレッドとして見ることができ、一人で実行します。
- 分離スレッドがどのスレッドを表し、もはやオブジェクト後。
- でも、まだ実行されている場合、偽の分離後、合流可能()==;
ケーススタディに参加します:
INT メイン(){ スレッドT(TSTART、" C ++ 11スレッド!" )。 COUT << t.joinable()<< ENDL。 もし(t.joinable())t.join(); // t.detach(); エラー COUT << t.joinable()<< てendl; // t.join(); エラー はcout << " 主な機能!" << てendl; システム(「一時停止」)。 }
彼らは参加呼び出すことができます前に、単に唯一のスレッドが呼び出しが戻ると、スレッドが終了していることを示し、アクティブで、合流可能()== falseを返します。
インラインボイドスレッド::参加() { // スレッドに参加し た場合(!合流可能()) _Throw_Cpp_error(_INVALID_ARGUMENT)。 CONST BOOL _Is_null = _Thr_is_null(_Thr)。 // クラン-Wparentheses-平等を避けてください ... ... }
上記t.join()は同じ結果を得る)(t.detach置き換えられます。
空デタッチ() { // スレッドを切り離し た場合(!合流可能()) _Throw_Cpp_error(_INVALID_ARGUMENT)。 _Thrd_detachX(_Thr)。 _Thr_set_null(_Thr)。 }
上記デタッチするファイルに定義されたスレッドである、我々は、アクティブなスレッドがデタッチを呼び出すことができる場合にのみ合流可能==真のスレッドを()、見ることができます。
〜スレッド()_NOEXCEPT { // クリーンアップする 場合(合流可能()) _XSTDは(終了)。 }
スレッドはどちらも参加しなかったり通話を切り離す呼び出すと、スレッドが終了したスレッドオブジェクトが破棄されると合流可能()== trueの場合、それから、それが終了する呼び出します()。
4.3スレッドIDを取得
スレッドは、スレッド識別子IDであり、C ++標準は、2つのモードは、スレッドIDを取得提供します。
- thread_obj.get_id();
- std :: this_thread :: GET_ID()
もう一つ注意すべきは、つまり、0の値を返しますGET_ID任意のスレッドスレッドOBJ呼び出しを表していない、空のスレッドオブジェクトです。
さらに、場合スレッドまたは連結可能デタッチ()==偽、GET_ID呼び出しが0の結果を返します。
coutの<< t.get_id()<< ' ' << this_thread :: GET_ID()<< てendl; // t.detach(); t.join(); coutの << t.get_id()<< ' ' <<はstd :: this_thread :: GET_ID()<<てendl;
4.4交換スレッドスレッド表現
また、上述のスレッドがスレッドオブジェクトによって単離し、表現することができるデタッチする、または別のスレッドに移動し、あなたは、2つのスレッドによって表される為替スワップスレッドオブジェクトに使用することができます。
二つのスレッドを見て交換の例。
int型の TSTART(のconst 文字列&TNAME){ coutの << " スレッドテスト!" << TNAME << てendl; リターン 0 ; } int型のmain(){ スレッドT1(TSTART、" C ++ 11 thread_1!" )。 スレッドT2(TSTART、" C ++ 11 thread_2!" ); COUT << " 現在のスレッドID:" << this_thread :: GET_ID()<< ENDL。 裁判所未満 << " スワップ前:thread_1 ID:" << t1.get_id()<< " thread_2 ID:" << t2.get_id()<< ENDL; t1.swap(T2); COUT << " スワップ後:" << " thread_1 ID:" << t1.get_id()<< " thread_2 ID:" << t2.get_id()<< ENDL; // t.detach(); t1.join(); t2.join(); }
結果:
スレッドのテスト!C ++ 11 thread_1! スレッドのテスト!C ++ 11 thread_2! 現在のスレッドID:39308 スワップ前:thread_1 ID:26240 thread_2 ID:37276 スワップ後:thread_1 ID:37276 thread_2 ID:26240
ここでは、スレッド::スワップ機能があります。
ボイドスワップ(スレッド&_Other)_NOEXCEPT { // _Otherとスワップ _STDスワップ(_Thr、_Other._Thr)。 }
私たちは、基本的なスレッドオブジェクトのハンドルによって保持されているスワップの交流の過程を見ることができます。
約C ++ここでの新しい標準スレッドへの基本的な導入をマルチスレッド、そして出会ったシンプルな存在であることを参照してください。
無料の書き込み記事の背後にあるスレッドの安全性およびその他の上級管理職のトピック、について説明します。