2011-10-23 10 views
6

私の短縮、簡略化されたクラスは見えます:「ネスト」scoped_lock

class A 
{ 
    public: 
    // ... 
    methodA(); 
    methodB(); 

    protected: 
    mutable boost::mutex m_mutex; 
    sometype* m_myVar; 
} 

A::methodA(int someParam) 
{ 
    boost::mutex::scoped_lock myLock(m_mutex); 
    m_myVar->doSomethingElse(); 
} 

A::methodB(int someParam) 
{ 
    boost::mutex::scoped_lock myLock(m_mutex); 
    m_myVar->doSomething(); 
    this->methodA(someParam); 
} 

私はm_myVarにアクセスを同期したいと思います。 A::methodB()を呼び出すときに、スレッドが再び渡す場合同じスレッドをブロックしていないscoped_lockを作るためにどのような方法がありますA::methodA()

の最初の行にブロック二回と明らかに同じミューテックスでロックに動作しますか?

確かに、私は単にm_mutex.unlock()と呼ぶことができます。しかし、これはロックを待っている他のスレッドも解放します。これは絶対に私が望むものではありません。

敬具 トビアス

+8

'boost :: mutex'の代わりに' boost :: recursive_mutex'を使用してください。 – BatchyX

答えて

12

これは、何回もデッドロックすることなく同じスレッドでロックを取得できるようにするためのものです。 boost::mutex

+1

+1:明白なことを言っているようです:Pありがとう! – Atmocreations

0

試みでは、現在のスレッドIDを取得し、スレッドIDがあればMethodB.Otherwiseを実行するスレッドIDと同じである場合にのみ実行を継続すべき失敗した場合は、methodAでのtryLockを使用することができます試行が成功すると正常に実行を続けることができます。

+1

これは起こりそうな競合状態のようです。 – user786653

+0

私の意見では通常、BatchyXのコメントが最も良い答えです。しかし、私は本当にここで競争状態を見ていない。あなたは私を説明できますか? – AlexTheo

+0

申し訳ありませんが、あなたはおそらくそれがうまくいくと思っています。 – user786653

4

ここではさまざまなことがあります。同じスレッド内で複数回取得できる再帰的なミューテックスを使用することができます。または、methodAを実装およびロックなしでプライベートメソッドに分割し、プライベート実装をロックして呼び出しているパブリックメソッドに分割できます。次にmethodBはロックを保持している間に内部実装を呼び出します。このメソッドはプライベートなので、すべての用途を制御でき、ロックを保持している間だけ実装メソッドが呼び出されるようにすることができます。