2012-02-27 3 views
1

私のアプリケーションはいくつかの小さなドメインに分かれており、それらの間の依存関係を減らすためにコンテキストオブジェクトを使用します。簡単な例を考えてみましょう:コンテキストオブジェクトの同期

class SomeType1; 
class SomeType2;  
class dummy; 

//context for first domain 
class foo 
{ 
public: 
    virtual void setPtr1 (SomeType1* val) = 0; 
    virtual SomeType2* getPtr2() = 0; 

    static foo* getCTX() 
    { 
     //statement bellow is a singleton which creates one instance of dummy and 
     //returns its address as foo* 
     return AppCTX::AccessorType<dummy>::getCTX<foo>(); 
    } 
    virtual ~foo(); 
}; 

//context for second domain 
class bar 
{ 
public: 
    virtual void setPtr2 (SomeType2* val) = 0; 
    virtual SomeType1* getPtr1() = 0; 
    static bar* getCTX() 
    { 
     //same as above but casts dummy* to bar* 
     return AppCTX::AccessorType<dummy>::getCTX<bar>(); 
    } 
    virtual ~bar(); 
}; 

//dummy is a singleton created in AppCTX::AccessorType<dummy> 
class dummy: public foo, public bar 
{ 
public: 
    virtual void setPtr1 (SomeType1* val) 
    { 
     ptr1 = val; 
    } 

    virtual SomeType1* getPtr1() 
    { 
     return ptr1; 
    } 

    virtual void setPtr2 (SomeType2* val) 
    { 
     ptr2 = val; 
    } 

    virtual SomeType2* getPtr2() 
    { 
     return ptr2; 
    } 
    virtual ~dummy(); 
private: 
    SomeType1* ptr1; 
    SomeType2* ptr2; 
}; 

私のドメインもそうPTR1及びPTR2は並列にアクセスすることができるコンテキストを使用する複数のスレッドを開始します。 setPtrsとgetPtrsをmutexと同期させる必要がありますか? ptr1とptr2が何とか壊れてしまう可能性はありますか?

答えて

1

getPtr関数とsetPtr関数をミューテックスすることはあまり重要ではありません。呼び出し元がポインタを取得してミューテックスを解放した後でも、それは受け取ったポインタを使って何でもしたいことができます。これは間違いなく複数のスレッドで問題を引き起こす可能性があります。

実際には、ロック機構をSomeType1クラスとSomeType2クラス自体に入れたいと思っています。たとえば、SomeType1の各メンバー関数の始めにミューテックスを取得し、各メンバー関数が戻る前にミューテックスを解放することができます。

メンバー関数の中には、すでにスレッドセーフであるものがあります。たとえば、メンバー変数やその他の共有リソースにアクセスしない場合、スレッド間で競合する可能性はありません。だから、それらをミューテックスする必要はありません。しかし、メンバー関数のそれぞれを見て、それらの関数で使用されるメンバー変数が予期せず変更された場合にどうなるかを尋ねる必要があります。その振る舞いが望ましくない場合、そのメンバ関数はmutexされるべきです。

しかし、実際のポインタ変数自体が壊れているのであれば、コンパイル対象のマシンアーキテクチャによって異なります。多くのシステム(32ビットポインタの割り当てがアトミック操作である)では、これはまったく問題にはなりません。その質問はより完全に答えられますhere

関連する問題