2012-02-27 47 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?有沒有可能ptr1和ptr2以某種方式被破壞?

回答

1

互斥你的getPtr和setPtr函數不會很有價值。即使在調用者獲得指針並釋放互斥鎖之後,它仍然可以對接收到的指針做任何事情。這肯定會導致多個線程的問題。

您實際上想要將自己的鎖定機制置於SomeType1和SomeType2類中。例如,您可能會在SomeType1的每個成員函數的開始處獲取互斥鎖,然後在每個成員函數返回之前釋放該互斥鎖。

您的某些成員函數可能已經是線程安全的。例如,如果他們不訪問成員變量或任何其他共享資源,那麼線程之間就不存在爭用的可能性。所以,你不需要對這些進行互斥。但是,您需要查看每個成員函數,然後問自己,如果這些函數使用的成員變量意外更改,會發生什麼情況。如果行爲不可取,那麼該成員函數應該被互斥。

但是,如果你擔心的是實際的指針變量本身被破壞,它取決於你正在編譯的機器結構。對於許多系統(爲其分配一個32位指針是一個原子操作),這根本不是問題。這個問題更全面地回答了here