2012-12-19 26 views
8

std::atomicを参照カウンタに使用するポインタ/弱ポインタ​​機構を実装しています(thisなど)。強いものに弱いのポインタを変換するために、私は強い参照カウンタがそうであれば C++はゼロ以外の場合std :: atomic_intをインクリメントします

  • ゼロでなければ

    • チェックをアトミックにする必要があり、それは
    • 何かが変更されたかどうかを知るインクリメント。

    std::atomic_intを使用してこれを行う方法はありますか?私はそれがcompare_exchangeの1つを使って可能でなければならないと思うが、私はそれを把握することができない。定義std::atomic<int> ref_count;

    int previous = ref_count.load(); 
    for (;;) 
    { 
        if (previous == 0) 
         break; 
        if (ref_count.compare_exchange_weak(previous, previous + 1)) 
         break; 
    } 
    

    previous考える

  • +3

    'のstd :: shared_ptr'は、原子参照カウンタを使用して、あなたが知っています。あなたはいつもソースをチェックすることができます。 – Pubby

    +1

    「何か変わったかどうかを知る」という部分はどういう意味ですか? – inf

    +0

    インクリメントされたかどうかは、==の前に0ではないかどうか。 –

    答えて

    3

    は前の値を保持します。 compare_exchange_weakは、失敗した場合に前の情報を更新することに注意してください。

    +0

    ref_count.load()はforループ内にありませんか?私は間違っているかもしれません。なぜなら、原子オプスの方法で考えるのは難しいからです。 :) – NoSenseEtAl

    +2

    @NoSenseEtAl 'compare_exchange_weak'は' previous'を参照して更新しますので、別の 'ref_count.load()'を実行する必要はありません。 – ymett

    1

    これはそれを行う必要があります。

    bool increment_if_non_zero(std::atomic<int>& i) { 
        int expected = i.load(); 
        int to_be_loaded = expected; 
    
        do { 
         if(expected == 0) { 
          to_be_loaded = expected; 
         } 
         else { 
          to_be_loaded = expected + 1; 
         } 
        } while(!i.compare_exchange_weak(expected, to_be_loaded)); 
    
        return expected; 
    } 
    
    +0

    既に値を変更しないことを決めた場合は、compare_exchangeを続行する必要はありません。 – ymett

    +0

    @ymett私はあなたに同意しますが、何らかの理由で私が他の2つの状態である「i」をインクリメントするかどうかの決定に基づいているので、何とかわかりません。 – inf

    +0

    一度だけ決める必要があります。決定を下すと( 'if'で)、あなたは終了します。 – ymett

    関連する問題