2012-07-25 2 views
5

スレッドセーフなコンテナクラスをゼロから作成しようとしていますが、私はアクセスメソッドから値を返すという問題に遭遇しました。 Windowsでの例:C++での重要なセクションと戻り値

myNode getSomeData() 
{ 
    EnterCriticalSection(& myCritSec); 
    myNode retobj; 
    // fill retobj with data from structure 
    LeaveCriticalSection(& myCritSec); 
    return retobj; 
} 

今、私はコードがクリティカルセクションを解放した後、別のスレッドが一緒に来て、すぐに最初のスレッドの前にretobjを上書きすることができますので、このタイプの方法はすべて、スレッドセーフではないと仮定戻る。したがって、スレッドセーフな方法でretobjを呼び出し元に返すエレガントな方法は何ですか?

+1

しかし、スタックにretobj保存されていますか? 「静的」と宣言されていない限り、コピーされたデータが上書きされることに問題はありません。 –

+0

何か奇妙なことが起こっていない限り、 'retobj'はスタック上になければならず、各スレッドはそれ自身のスタックを持つべきです。この種の競合条件は、事前に割り当てられたメモリを使用していて、共有を防止するためにアクセスをロックする必要がある場合に、より一般的です。 – ssube

+0

@inface、ok良い点、戻り値がスタックに格納されている限り、私は良いです。 – ThomasMcLeod

答えて

7

いいえ、各スレッドには独自のスタックがあり、それはretobjであるため、スレッドセーフです。

ただし、例外的に安全であるとは限りません。クリティカルセクションをRAIIスタイルのオブジェクトにラップすると、そのことが役に立ちます。以下のような何か...

class CriticalLock : boost::noncopyable { 
    CriticalSection &section; 

public: 
    CriticalLock(CriticalSection &cs) : section(cs) 
    { 
    EnterCriticalSection(section); 
    } 

    ~CriticalLock() 
    { 
    LeaveCriticalSection(section); 
    } 
}; 

使用法:

myNode getSomeData() 
{ 
    CriticalLock lock(myCritSec); // automatically released. 
    ... 
} 
2

これはC++で、retobjは自動保存タイプのため、スタックに格納されます。

すべてのスレッドには独自のスタックがあるため、返される前に別のスレッドがretobjの値を壊すことはできません。