2016-09-23 5 views
0

これは私が取り組んでいるプロジェクトで起こっていることの非常に基本的な例です。このシナリオは基本的に、現在のスレッドのリソースをすべて終了するまで他のすべての関数を呼び出す関数を呼び出す1つの関数です。ここに小さな例があります。関数が返るまでスレッドをロックする際の問題?

void functionA() 
{ 
    lockUntilDone(); 
    //do some magic 
    functionB(); 
    //do some more magic 
} 

void functionB() 
{ 
    lockUntilDone(); 
    //make some more magic 
    functionC(); 
} 

void functionC() 
{ 
    lockUntilDone(); 
    //make a little bit more magic 
} 

lockUntilDoneは() - 関数は実行だ終了と範囲の外になるまで、現在のスレッドでリソースをロックします。

私はスレッドとプロセスの使用について学び始めています。 functionAの実行中に発生する可能性のある問題は何ですか?このシナリオが拡張されたら、3つのレベルのロックの代わりに4,5,6などになりますか?あるいは、これはスレッドをロックし、関数内のリソースを処理する典型的な方法ですか?

答えて

1

3つ、4つ以上の入れ子レベルで追加の問題はありません。一般的な問題は、1レベルから複数レベルにスケールするときです。 std :: mutexは再帰的ではありません。つまり、既にロックしているスレッドからそれをやろうとしても、二度とロックすることはできません。したがって、lockUntilDoneはrecursive_mutexを使用する必要があります。それらはSTLでも提供されていますが、使用することはできますが、非再帰的なものほど効率的ではありません。

ただし、複数のネストされた関数から同じオブジェクトをロックする必要がある状況は一般的ではありません。それは問題ありませんが、それはコードをリファクタリングする必要があるという症状です。例えば、ロックは粗すぎる可能性があり、いくつかのロックに分割することができます。あるいは、メソッドのいくつかは実際には常にロックされたコンテキストから呼び出され、追加のロックを必要としないプライベートメソッドです。

個人的には、functionAでのみロックを行います。 functionBが私的でなくfunctionAの外で呼び出すことができる場合、私はすべての作業を行うlockを使わずにprivate functionBを作成し、functionAとそれを使用するpublic functionBからロックを行い、内部関数を呼び出します。

関連する問題