https://www.youtube.com/watch?v=3ZxZPeXPaM4学習ビデオ
データ競合
予測不可能なオブジェクトを読み取るとき(書き込み動作を行う少なくとも一つのスレッド)を読み書きする共通オブジェクトの複数のスレッドの存在は単純に、結果が生じ
、次のように
int num = 0;
void func(int &v)
{
for (int i = 0; i < 100000; ++i)
{
num = num + 1;
v++;
}
}
int main()
{
int v = 0;
std::vector<std::thread> ts;
for (int i = 0; i < 100; ++i)
{
ts.push_back(std::thread(func, std::ref(v)));
}
for (int i = 0; i < 100; ++i)
{
ts[i].join();
}
std::cout << num << ", " << v << std::endl;
return 0;
}
COUT千万、千万のない結果
読み書き制御対象ミューテックス
ミューテックスオブジェクトを呼び出す前に::読み取りおよび書き込みロックの操作は(ミューテックスを呼び出すことを忘れないでください::ロック解除は、オブジェクトを保持するために必要とされていない)ことができます
...
std::mutex mu;
void func()
{
...
mu.lock();
num += 1;
v += 1;
mu.unlock();
}
...
std :: lock_guard
ミューテックスのロック・アンロックブロックで例外がスローされた場合で、ロック解除と呼ばれる(またはロック解除が可能である呼び出すことを忘れ)されることはありません、
あなたはlock_guardの使用を検討することができます:
...
{
std::lock_guard<std::mutex> guard(mu);
v++;
num++;
}
...
私はそれが内部lock_guardがmutexを保持して、デストラクタでのミューテックスのメソッド呼び出しのロックを解除しようとするべきであると感じ
コントロールオブジェクトが完全にロックされていない書きます
両方が読み取られ、各サブスレッドに制御ミューテックスを記述しているものの、上記の例では、グローバル変数NUM、およびローカル変数vは、ある;
しかし、メインスレッドでは、2つのプロセスではまだされていない主内部含まなくてもよいです共有オブジェクト、
アプローチは、前ミューテックスオブジェクトがリソースの各使用がなければならないことを保証するために保護され、ミューテックスが拘束されることにリソースを標的とすることである
次のように
class LogFile {
std::mutex m_mutex;
ofstream f;
LogFile() {
f.open(...);
}
void shared_print(string id, int value) {
std::lock_guard<mutex> guard(m_mutex);
f << id << ", " << value << endl;
}
// ofstream &getStream() { return f; }
}
上記の例では、Fログファイルオブジェクトは同じように、コメントの最後の行として、公開覚えていないことができ
、それはofstreamのであればもちろんのことも問題ありません。
「偶然」ログファイル:: Fを暴露する可能性のある他の事情がある、次のように:
void LogFile::processf(void fun(ofstream&))
{
fun(this->f);
}
ここでは「偶然」Fオブジェクト参照がそこに関数fun、楽しみに渡され、ログファイル:: fはミューテックスの保護を失いました
概要
- 読み書きするためにリソースオブジェクトを制御するために、ミューテックスを使用して、
- 内部リソースオブジェクトクラスのラッパーを公開しないでください。
- なお、インタフェース設計の合理性