C++11マルチスレッドと同時制御
3988 ワード
C++11にはプラットフォームにまたがるスレッドライブラリとセットの同時制御ライブラリがパッケージされています.ここで一緒に記録します.
一、Threadライブラリ
C++11にはスレッドライブラリがパッケージされており、
基本的なスレッド操作の流れを以下に示します.
スレッドの初期化時に入力される最初のパラメータは、スレッドが実行する関数であり、その後、可変パラメータがスレッド関数に使用されるパラメータを入力することができる.メインスレッドはget_を使用できますidは対応するスレッドidを取得し、このidはシステムが割り当てたidではなく、システムidを取得するには各オペレーティングシステムのオリジナルのインタフェースが必要であることに注意しなければならない.一般的な関数に加えて、クラスオブジェクトのメンバー関数も入力できます.
上記のコードでは、
二、反発量mutex
c++11はまた、マルチスレッドによる共有変数へのアクセス制御のためのmutexライブラリを提供する.すべての関連クラスは
シーケンス番号
名前
用途
1
std::mutex
最も基本的で最もよく使われる反発クラス
2
std::recursive_mutex
同一スレッド内で再帰(再入)可能な反発クラス
3
std::timed_mutex
mutex機能に加え、タイムリミット要求ロック機能も備えています.
4
std::recursive_timed_mutex
同じスレッド内で再帰(再入)可能なtimed_mutex
基本操作は
上記の例ではlockをtry_に変更するとlockは、最終出力が5000未満になる可能性があります.また、2つの点に注意してください. C++11に追加された スレッドのパラメータについては、ref()で参照パラメータを識別する必要があります.そうしないと、 とエラーが発生します.
三、MutexLockGuard
C++のRAII特性は多くの場所で応用されており、mutexライブラリもlock_を提供している.guardクラスは、プログラムがコンストラクション関数でmutexをロックし、コンストラクションでロックを解除することを実現することができる.
最も基本的なのはlock_guardテンプレート
lock_guardテンプレートは、mutexを操作するための最も基本的なRAII特性を提供します.さらにunique_を使用することもできますlock,unique_lockは、構造後にロックを解除するなど、より多くのインタフェースを提供し、構造が析出するまでロックを解除する必要はありません.
lock_よりguard,unique_lockはより柔軟になりますが、スペースと効率も遅くなります.
四、条件変数waitとnotify
C++11はまた、mutexに合わせて条件変数を提供し、信号量の制御機構を実現することができる.基本的な操作は
条件変数
一、Threadライブラリ
C++11にはスレッドライブラリがパッケージされており、
thread
ファイルにあり、基本的なスレッドに必要な各種関数があります.基本的なスレッド操作の流れを以下に示します.
#include
#include >
using namespace std;
void ThreadFunc(int nThreadNum)
{
cout << "INFO: Num is " << nThreadNum << endl;
}
int main()
{
thread TestThread(ThreadFunc, 1);
cout << TestThread.get_id() << endl;
TestThread.join();
return 0;
}
スレッドの初期化時に入力される最初のパラメータは、スレッドが実行する関数であり、その後、可変パラメータがスレッド関数に使用されるパラメータを入力することができる.メインスレッドはget_を使用できますidは対応するスレッドidを取得し、このidはシステムが割り当てたidではなく、システムidを取得するには各オペレーティングシステムのオリジナルのインタフェースが必要であることに注意しなければならない.一般的な関数に加えて、クラスオブジェクトのメンバー関数も入力できます.
ThreadFuncObj TestObj;
thread TestThread(&ThreadFuncObj::ThreadFunc, &TestObj, 1);
上記のコードでは、
ThreadFuncObj::ThreadFunc
は非静的であるため、このタイプの関数ポインタを作成するために&を追加する必要があります.静的メンバー関数であれば追加しないでください.エディタはデフォルトで関数ポインタです.二、反発量mutex
c++11はまた、マルチスレッドによる共有変数へのアクセス制御のためのmutexライブラリを提供する.すべての関連クラスは
ヘッダファイルにあります.全部で4つの反発クラスがありますシーケンス番号
名前
用途
1
std::mutex
最も基本的で最もよく使われる反発クラス
2
std::recursive_mutex
同一スレッド内で再帰(再入)可能な反発クラス
3
std::timed_mutex
mutex機能に加え、タイムリミット要求ロック機能も備えています.
4
std::recursive_timed_mutex
同じスレッド内で再帰(再入)可能なtimed_mutex
基本操作は
lock
,try_lock
,unlock
の3種類である.簡単な例を次に示します#include
#include
#include
using namespace std;
void AddCount(mutex &mutexTest, int &nCount)
{
for (int i = 0; i < 1000; ++i)
{
mutexTest.lock();
++nCount;
mutexTest.unlock();
}
}
int main()
{
thread arrThreads[5];
mutex mutexTest;
int nCount = 0;
for (auto& threadIte : arrThreads)
{
threadIte = thread(AddCount, ref(mutexTest), ref(nCount));
}
for (thread& threadIte : arrThreads)
{
threadIte.join();
}
cout << nCount << endl;
return 0;
}
上記の例ではlockをtry_に変更するとlockは、最終出力が5000未満になる可能性があります.また、2つの点に注意してください.
for(a : b)
という操作はpythonのfor a in b
に似ています.ただし、aの値を変更するなど、bのaを遍歴操作する場合は、参照記号&を付ける必要があります.加えなくても操作できますが、オブジェクトはbの中のaではなくコピーのオブジェクトです.上記の例のように、threadIte
は、threadがコピー構造をサポートしていないため、参照が付加されていない場合、エラーを報告する.三、MutexLockGuard
C++のRAII特性は多くの場所で応用されており、mutexライブラリもlock_を提供している.guardクラスは、プログラムがコンストラクション関数でmutexをロックし、コンストラクションでロックを解除することを実現することができる.
最も基本的なのはlock_guardテンプレート
lock_guard _guard(mutexTest);
lock_guardテンプレートは、mutexを操作するための最も基本的なRAII特性を提供します.さらにunique_を使用することもできますlock,unique_lockは、構造後にロックを解除するなど、より多くのインタフェースを提供し、構造が析出するまでロックを解除する必要はありません.
unique_lock _guard(mutexTest);
_guard.unlock();
lock_よりguard,unique_lockはより柔軟になりますが、スペースと効率も遅くなります.
四、条件変数waitとnotify
C++11はまた、mutexに合わせて条件変数を提供し、信号量の制御機構を実現することができる.基本的な操作は
wait
+notify_one/notify_all
ですvoid AddCount(mutex& mutexTest, condition_variable &cv, int& nCount)
{
for (int i = 0;i < 100; ++i)
{
unique_lock _guard(mutexTest);
nCount += 1;
cv.notify_one();
}
}
void Subcount(mutex& mutexTest, condition_variable& cv, int& nCount)
{
for (int i = 0; i < 100; ++i)
{
unique_lock _guard(mutexTest);
if (nCount <= 0)
cv.wait(_guard);
nCount -= 0;
}
}
wait
が呼び出されると、スレッドは入力された反発量をロック解除し、対応する信号量を待機し、他のスレッドのnotify
信号を受信すると、反発量のロックを再試行し、wait
以降のプログラムを実行する.条件変数
condition_variable
クラスを使用する場合は、unique_lock
で提供される反発量クラスを使用する必要があります.他のタイプを使用する場合は、condition_variable_any
を使用します.