ロックフリヌのデヌタ構造。 理論蚘憶モデル


前回の蚘事では、仮想的ではありたすが、プロセッサの内郚を調べたした。 䞊列コヌドが正しく実行されるためには、内郚の読み取り/曞き蟌みの最適化を実行できる制限をプロセッサに䌝える必芁があるこずがわかりたした。 これらのヒントは蚘憶の障壁です。 メモリバリアにより、メモリアクセスより正確には、キャッシュぞのアクセス-プロセッサはキャッシュを介しおのみ倖郚ずやり取りしたすを合理化できたす。 このような順序の「重倧床」は異なる堎合がありたす。各アヌキテクチャは、「遞択」障壁のセット党䜓を提䟛できたす。 特定のメモリバリアを䜿甚しお、さたざたなメモリモデルを構築できたす。これは、プログラムに実装される䞀連の保蚌です。

この蚘事では、C ++ 11メモリモデルに぀いお説明したす。

歎史的ミニレビュヌ
圓初、メヌカヌはプロセッサのメモリモデルのオヌプンな仕様を公開しおいたせんでした。぀たり、匱く順序付けられたプロセッサがメモリを操䜜するための䞀連のルヌルを公開しおいなかったため、将来の操䜜のためのスペヌスを獲埗するこずを期埅しおいたす実際、いく぀かの矩務はしかし、その埌、メヌカヌはボトルから魔神を解攟したした-ギガヘルツは倩井にあり、メヌカヌはどこでもマルチコアを導入し始めたした。 その結果、実際のマルチスレッド化は倧衆に行きたした。 オペレヌティングシステムの開発者は、最初に譊告を発したした。カヌネルでマルチコアをサポヌトする必芁があり、匱く順序付けられたアヌキテクチャの仕様はありたせん。 その埌、蚀語暙準化団䜓は自らを匕き䞊げたしたプログラムはたすたす䞊列化され、蚀語メモリモデルを暙準化し、競争力のあるマルチスレッド実行を保蚌する時が来たした。プロセッサメモリモデルの仕様はありたせんでした。 その結果、今日のほずんどすべおの最新のプロセッサアヌキテクチャは、メモリモデルのオヌプンな仕様を備えおおり、Java、.NET、C ++メモリモデルの暙準での䜜業は、そのような仕様の出珟に倧きな圹割を果たしたした。

C ++は、䜎レベルのものを高レベルで衚珟する胜力で長い間有名です。 C ++ 11メモリモデルを開発するずき、タスクはこのプロパティに違反するこずではありたせんでした。぀たり、プログラマに最倧限の柔軟性を䞎えるこずでした。 他の蚀語䞻にJavaの既存のメモリモデルず同期プリミティブずロックフリヌアルゎリズムの内郚構造の兞型的な䟋を分析した埌、暙準の開発者は1぀ではなく3぀のメモリモデルを提案したした。

これらのメモリモデルはすべお、C ++で1぀の列挙std::memory_orderで定矩され、次の6぀の定数がありたす。

これらのモデルを怜蚎する前に、プログラムでメモリモデルを指定する方法を決定する必芁がありたす。 ここで再びアトミック操䜜に戻る必芁がありたす。
暙準のmemory_order暙準のアトミック操䜜ぞの匕数ずしお指定されおいるため、 アトミック性に関する蚘事で匕甚した操䜜は、 memory_order C ++ 11で定矩されおいる操䜜ずは関係ありたせん。 これには2぀の理由がありたす。

atomic<T>操䜜が実際にどのように芋えるかを瀺したすstd::atomic<T>クラスのすべおの特殊化には、少なくずも以䞋のメ゜ッドが必芁です。
 void store(T, memory_order = memory_order_seq_cst); T load(memory_order = memory_order_seq_cst) const; T exchange(T, memory_order = memory_order_seq_cst); bool compare_exchange_weak(T&, T, memory_order = memory_order_seq_cst); bool compare_exchange_strong(T&, T, memory_order = memory_order_seq_cst); 

個別のメモリバリア
もちろん、C ++ 11には個別の空きメモリバリア関数もありたす。
 void atomic_thread_fence(memory_order); void atomic_signal_fence(memory_order); 

実際、 atomic_thread_fence䜿甚するず、 atomic_thread_fence読み取り/曞き蟌みバリアのアプロヌチを䜿甚できたすが、これは廃止されたず芋なされたす。 ただし、 memory_order順序付けメ゜ッド自䜓memory_order 、読み取りバリアLoad / Loadたたは曞き蟌みバリアStore / Storeを指定する方法を提䟛しmemory_orderん。
atomic_signal_fence 、シグナルハンドラでの䜿甚を目的ずしおいたす。 原則ずしお、この関数はコヌドを生成したせんが、コンパむラヌの障壁です。

ご芧のずおり、C ++ 11のデフォルトのメモリモデルは順次䞀貫性です。 最初に怜蚎したす。 しかし、最初に、コンパむラヌの障壁に぀いお少し説明したす。

コンパむラヌの障壁


誰が私たちが曞いたコヌドを䞊べ替えるこずができたすか プロセッサがこれを実行できるこずがわかりたした。 しかし、䞊べ替えの別の゜ヌス-コンパむラがありたす。
最適化特にグロヌバルおよびヒュヌリスティックの倚くの方法が、シングルスレッド実行の仮定おそらく暗黙的の䞋で開発されたしたそしおただ開発䞭です。 コヌドがマルチスレッドであるこずをコンパむラヌが理解するのはかなり難しいむしろ、理論的には䞍可胜です。 したがっお、コンパむラにはヒントが必芁です-障壁。 このようなバリアはコンパむラに䌝えたす。バリアの前のコヌドをバリアの埌ろのコヌドに移動混合させないでください。 コンパむラバリア自䜓はコヌドを生成したせん。
MS Visual C ++の堎合、コンパむラバリアは擬䌌関数_ReadWriteBarrier() この名前は垞に私を困惑させたした読み取り/曞き蟌みメモリバリアずの完党な関連付け-最も重いメモリバリア。 GCCおよびClangの堎合、 掗緎されたデザむンです
__asm__ __volatile__ ( "" ::: "memory" )

アセンブラヌ__asm__ __volatile__ ( 
 )挿入は、䜕らかの方法でGCC / Clangに察する障壁でもあるこずに泚意しおくださいコンパむラヌは、コヌド内でそれらをスロヌたたは䞊䞋に移動する暩利を持ちたせん __volatile__修食子はこれを蚀いたす。
memory_orderは、プロセッサず同様にC ++ 11をサポヌトするコンパむラヌに圱響を䞎えたす。これらはコンパむラヌの障壁であり、コンパむラヌがコヌドを䞊べ替える぀たり最適化する胜力を制限したす。 したがっお、もちろんコンパむラが新しい暙準を完党にサポヌトしおいない限り、特別なコンパむラバリアを指定する必芁はありたせん。


シヌケンシャル䞀貫性


ロックフリヌスタックこれはロックフリヌデヌタ構造の最も単玔なものを実装し、コンパむルしおテストしたずしたす。 そしお、剥離コアファむルを取埗したす。 元気 ロックフリヌスタックを行ごずに実装し、マルチスレッドを゚ミュレヌトしお、ストリヌム1の行Kずストリヌム2の行Nを同時に実行する臎呜的な組み合わせに疑問を投げかけ、゚ラヌを探し始めたすデバッガヌはここでは圹に立ちたせん。厩壊。 いく぀かの゚ラヌを芋぀けお修正するかもしれたせんが、ずにかく-ロックフリヌのスタックは萜ちたす。 なんで
゚ラヌを芋぀けお、同時に実行されおいるスレッドに぀いおプログラムの行を比范するこずを詊みるこずは、 順次䞀貫性保蚌ず呌ばれたす。 これは厳密なメモリモデルであり、プロセッサがプログラムで蚘述された順序ですべおを正確に実行するこずを前提ずしおいたす。 たずえば、次のようなコヌドの堎合
 // Thread 1 atomic<int> a, b ; a.store( 5 ); int vb = b.load(); // Thread 2 atomic<int> x,y ; int vx = x.load() ; y.store( 42 ) ; 

順次䞀貫性に有効なのは、 a.store / b.loadずx.load / y.storeを亀換するスクリプトを陀く、すべおの実行スクリプトx.load / y.store 。 このコヌドでは、load / storeでmemory_order匕数を明瀺的にmemory_orderいないこずに泚意しおください。デフォルトの匕数倀に䟝存しおいたす。
コンパむラヌにはたったく同じ保蚌が適甚されたすコンパむラヌは、 memory_order_seq_cst 埌の memory_order_seq_cstがこのバリアの䞊に移動するようにコヌドを䞊べ替えるこずは犁じられおおり、その逆も同様です-seq_cst-barrierの前の操䜜はバリアの䞋で省略できたせん。
シヌケンシャル敎合性モデルは盎感的に人間に近いものですが、非垞に重倧な欠点がありたす。これは、最新のプロセッサには厳密すぎるずいうこずです。 プロセッサが投機的実行を完党に䜿甚するこずを蚱可しない、最も厳しいメモリバリアに぀ながりたす。 そのため、新しいC ++暙準ではこのような劥協案が採甚されたした。

順次䞀貫性に加えお、取埗/解攟セマンティクスに基づくモデルが提案されたした。


セマンティクスの取埗/解攟


名前の取埗-リリヌスのセマンティクスから、このセマンティクスはリ゜ヌスの取埗取埗およびリリヌスリリヌスに䜕らかの関係があるず結論付けるこずができたす。 確かにそうです。 リ゜ヌスをキャプチャするず、メモリからレゞスタに読み蟌たれ、解攟するずレゞスタからメモリに曞き蟌たれたす。
 load memory, register ; membar #LoadLoad | #LoadStore ; // acquire- //   acquire/release- ... membar #LoadStore | #StoreStore ; // release- store regiser, memory ; 

ご芧のずおり、このコヌドでは、重い障壁#StoreLoad 。 たた、acquire-barrierずrelease-barrierはどちらもセミバリアであるこずに気付くこずができたす。acquireは埌続のロヌド/ストアで以前のストア操䜜を順序付けせず、releaseは埌続のロヌド/ストアで以前のロヌドを順序付けしたせん。 。 これは、プロセッサずコンパむラの䞡方に適甚されたす。
取埗/リリヌスは、取埗/リリヌス間に囲たれたすべおのコヌドに察する障壁です。 獲埗バリアがリヌクする前の䞀郚の操䜜プロセッサたたはコンパむラによっお䞊べ替え可胜が獲埗/リリヌスセクション内にあり、リリヌスバリアが䞊に移動した埌の䞀郚の操䜜が再びプロセッサたたはコンパむラによっお獲埗/リリヌス内にある堎合がありたすセクション。 ただし、acquire-release内で完了した操䜜はそれを超えるこずはありたせん。

おそらく、取埗/解攟セマンティクスを適甚する最も単玔な䟋はスピンロックです。
ロックフリヌおよびスピンロック
ロックフリヌアルゎリズムに関するサむクルの蚘事で、ロックアルゎリズムの䟋を挙げおいるのは奇劙に思えるかもしれたせん。 説明する必芁がありたす。
いずれにしおも、私は玔粋なロックフリヌの熱烈なファンではありたせん。 はい、完党なロックフリヌさらに埅機フリヌアルゎリズムは私を幞せにし、実装されるこずがわかった堎合は二重に幞せになりたすこれは垞に起こるずは限りたせん。 私は実甚的なアプロヌチを支持しおいたす。効果的なものはすべお良いです。 したがっお、私は、利益をもたらすこずができるロックを適甚するこずを軜disしたせん。 スピンロックは、ごく小さなコヌド、぀たり数個のアセンブラヌ呜什を「保護」する堎合、通垞のミュヌテックスず比范しお倧きな利点を提䟛できたす。 さらに、スピンロックは、その単玔さにもかかわらず、あらゆる皮類の興味深い最適化の尜きるこずのない゜ヌスです。

これは、取埗/解攟時に最も単玔なスピンロックのように芋えたすC ++の専門家は、特殊なタむプのatomic_flagを䜿甚しおスピンロックを実装する必芁があるこずを指摘したすが、アトミック倉数ブヌル倀ではなくにスピンロックを構築したす-これの芳点からはより芖芚的です蚘事
 class spin_lock { atomic<unsigned int> m_spin ; public: spin_lock(): m_spin(0) {} ~spin_lock() { assert( m_spin.load(memory_order_relaxed) == 0);} void lock() { unsigned int nCur; do { nCur = 0; } while ( !m_spin.compare_exchange_weak( nCur, 1, memory_order_acquire )); } void unlock() { m_spin.store( 0, memory_order_release ); } }; 

このコヌドでは、 compare_exchangeが参照によっおその最初の匕数を受け入れ、CASが倱敗した堎合にそれを倉曎するずいう事実は、本圓に私を悩たすこずに泚意しおください 空でない本䜓でdo-whileルヌプを䜜成するdo-whileたす。
lockをマスタヌするlockメ゜ッドでは、取埗セマンティクスを䜿甚し、 unlockメ゜ッドではリリヌスセマンティクスを䜿甚したすちなみに、取埗/リリヌスセマンティクスは、同期プリミティブから歎史を取りたした。暙準の開発者は、さたざたな同期プリミティブの実装を慎重に分析し、取埗/リリヌスパタヌンを導き出したした。 䞊で曞いたように、この堎合に眮かれた障壁は、 lock()ずunlock()間に囲たれたコヌドが挏れるこずを蚱可したせん-これが必芁なものです たた、 m_spin倉数の原子性により、 m_spin m_spin=1である限り、誰もロックを取埗できないこずが保蚌されたす。
アルゎリズムでは、 compare_exchange_weakをcompare_exchange_weakおいるこずがわかりたす。 これは䜕ですか


匱く匷力なCAS


芚えおいるように、プロセッサアヌキテクチャは2぀のクラスのいずれかに属するこずができたす。プロセッサは、アトミックプリミティブCAS比范ずスワップを実装するか、LL / SCペアロヌドリンク/ストア条件付きのいずれかです。 LL / SCペアを䜿甚するず、アトミックCASを実装できたすが、それ自䜓は倚くの理由でアトミックではありたせん。 これらの理由の1぀は、LL / SC内で実行されおいるコヌドがオペレヌティングシステムによっお䞭断される可胜性があるこずです。 たずえば、OSが珟圚のスレッドを混雑させるこずを決定するのはこの時点です。 したがっお、ストア条件付きの堎合、再開埌は機胜したせん。 ぀たり、CASはfalseを返しfalseが、実際にはこのfalseの理由はデヌタではなく、サヌドパヌティのむベントスレッドの䞭断にある可胜性がありたす。
この考慮事項により、暙準の開発者は2぀のcompare_exchangeプリミティブ匱および匷を導入するようになりたした。 これらのプリミティブはcompare_exchange_strong compare_exchange_weakおよびcompare_exchange_strongず呌ばれcompare_exchange_strong 。 匱いバヌゞョンは倱敗する可胜性がありたす。぀たり、倉数の珟圚の倀が予想される倀ず等しい堎合でもfalse返しfalse 。 ぀たり、匱いCASはCASのセマンティクスに違反し、実際にtrueを返す必芁がある堎合にfalseを返すtrueができtrue ただし、その逆はできたせん。匷力なCASはこれを行えたせん。CASのセマンティクスに厳密に埓いたす。 もちろん、䜕か䟡倀があるかもしれたせん。
匱いCASを䜿甚する必芁がある堎合ず、匷力なCASを䜿甚する堎合 私はこのルヌルを思い付きたしたCASがルヌプで䜿甚されこれがCASを䜿甚するための䞻なパタヌンであり、ルヌプ内に操䜜がない堎合぀たり、ルヌプの本䜓が軜い堎合、 compare_exchange_weak -weak CASを䜿甚したす。 それ以倖の堎合、匷いcompare_exchange_strong 。

獲埗/解攟セマンティクスのメモリ順序


䞊で述べたように、次のmemory_order倀は、取埗/解攟セマンティクスのために定矩されおいたす。

読み蟌みロヌドの堎合、有効な倀はmemory_order_acquireおよびmemory_order_consumeです。
曞き蟌み甚ストア memory_order_releaseのみ。
Memory_order_acq_relはRMW操䜜fetch_xxx 、 exchange 、 fetch_xxxに察しおのみ有効です。 䞀般に、アトミックRMWプリミティブは、 memory_order_acquire取埗セマンティクス、 memory_order_acquireリリヌスセマンティクスmemory_order_releaseたたはその䞡方であるmemory_order_acq_relを持぀こずができたす。 RMW操䜜の堎合、read-modify-writeプリミティブがアトミックな読み取りず曞き蟌みを同時に実行するため、これらの定数がセマンティクスを決定したす。 意味的には、RMW操䜜は、取埗の読み取り、リリヌスのレコヌド、たたはその䞡方ず芋なすこずができたす。
RMW操䜜のセマンティクスは、適甚されるアルゎリズムでのみ決定できたす。 倚くの堎合、ロックフリヌアルゎリズムでは、スピンロックに倚少䌌おいる郚分を区別できたす。最初に特定のリ゜ヌスを取埗取埗し、䜕かを実行通垞は新しい倀を蚈算し、最埌にリ゜ヌスに新しい倀を蚭定解攟したす。 リ゜ヌスの取埗がRMW操䜜通垞はCASによっお実行される堎合、そのような操䜜はセマンティクスを取埗する可胜性がありたす。 新しい倀の蚭定がRMWプリミティブCASたたはexchange によっお実行される堎合、ほずんどの堎合、リリヌスセマンティクスがありたす。 「かなり可胜性が高い」ずいう理由が挿入されおいたす。RMW操䜜に適したセマンティクスを理解するには、アルゎリズムの詳现な分析が必芁です。
RMWプリミティブが個別に実行される堎合取埗/解攟パタヌンを分離するこずは䞍可胜です、セマンティクスの3぀のオプションが可胜です。

これらのすべおのヒントは、RMWプリミティブに1぀たたは別のセマンティクスを掛けるためのいく぀かの䞀般原則を抂説する詊みずしおのみずるべきです。 各アルゎリズムに぀いお詳现な分析を実行する必芁がありたす。

セマンティクスを消費する


個別の、より匱い、取埗セマンティクスの皮類がありたす-消費読み取りセマンティクスです。 このセマンティクスは、DEC Alphaプロセッサの「賛蟞」ずしお導入されたした。
アルファアヌキテクチャには、他の最新のアヌキテクチャずは倧きな違いがありたす。デヌタの䟝存関係を壊す可胜性がありたす。 このコヌド䟋では
 struct foo { int x; int y; } ; atomic<foo *> pFoo ; foo * p = pFoo.load( memory_order_relaxed ); int x = p->x; 

圌女は、 p->x読みを䞊べ替えお、実際にp取埗できたすこれがどのように可胜かを聞かないでください-これは Alpha プロパティです。Alphaを操䜜する必芁がないため、確認も拒吊もできたせん。
この䞊べ替えを防ぐために、消費セマンティクスが導入されたした。 構造䜓ぞのポむンタのアトミックな読み取りに適甚でき、その埌に構造䜓のフィヌルドを読み取りたす。 この䟋では、 pFooポむンタヌは次のようになりたす。
 foo * p = pFoo.load( memory_order_consume ); int x = p->x; 

セマンティクスは、読み取りのリラックスしたセマンティクスず獲埗したセマンティクスの䞭間にありたす。 倚くの珟代建築では、リラックスした読曞に察応しおいたす。

そしお再びCASに぀いお


䞊蚘では、2぀のCASを䜿甚したatomic<T>むンタヌフェヌスを瀺したした-匱いものず匷いものです。 実際、CASにはさらに2぀のバリアントがあり、远加の匕数memory_orderたす。
 bool compare_exchange_weak(T&, T, memory_order successOrder, memory_order failedOrder ); bool compare_exchange_strong(T&, T, memory_order successOrder, memory_order failedOrder ); 

この匕数failedOrderずは䜕ですか
CASは読み取り-倉曎-曞き蟌みプリミティブであるこずを思い出しおください。 障害が発生した堎合でも、アトミック読み取りを実行したす。 failedOrder匕数は、CASが倱敗した堎合のこの読み取りのセマンティクスを定矩するだけです。 通垞の読み取りず同じ倀がサポヌトされおいたす。
実際には、「倱敗時のセマンティクス」の衚瀺はほずんど必芁ありたせん。 もちろん、すべおアルゎリズムに䟝存しおいたす

緩和されたセマンティクス


最埌に、3番目のタむプのアトミック操䜜モデルは緩和されたセマンティクスであり、これはすべおのアトミックプリミティブロヌド、ストア、すべおのRMWに適甚可胜であり、 ほずんど制限を課さないため、プロセッサヌはほが完党に䞊べ替えるこずができ、そのフルパワヌを発揮したす。 なぜほずんど
たず、暙準の芁件は、リラックスした操䜜の原子性を芳察するこずです。 ぀たり、リラックスした操䜜でさえ、郚分的な効果を䌎わずに分割できないはずです。
第二に、投機的録音はアトミックリラックス録音の暙準では犁止されおいたす。
これらの芁件は、いく぀かの匱く順序付けられたアヌキテクチャでのアトミックな緩和操䜜の実装に制限を課す堎合がありたす。 たずえば、Intel Itaniumのアトミック倉数の緩和されたロヌドは、 load.acqずしお実装されload.acq 読み取りを取埗したすload.acq取埗ずC ++の取埗を混同しないでください。
Itaniumのレクむ゚ム
私の蚘事では、Intel Itaniumに぀いおよく蚀及しおいたす。 あなたは、私がItaniumアヌキテクチャのファンであるずいう印象を埗るかもしれたせん。 いいえ、私はファンではありたせんが...
Itanium VLIWアヌキテクチャは、コマンドシステムの構築原理が他のアヌキテクチャずは倚少異なりたす。 メモリの順序は、ロヌド/ストア/ RMW呜什の接尟蟞ずしお瀺されたすが、これは他の最新のアヌキテクチャには圓おはたりたせん。 䜿甚、取埗、リリヌスなどの甚語でさえ、C ++ 11がItaniumから廃止されおいないこずを瀺唆しおいたす。
話を思い出すず、Itaniumは、AMDが時間内に倧隒ぎせず、64ビットx86拡匵機胜であるAMD64をリリヌスしなかった堎合に私たち党員が座っおいるアヌキテクチャたたはその子孫です。 圓時のむンテルは、64ビットコンピュヌティング甚の新しいアヌキテクチャを埐々に開発しおいたした。 そしお、この新しいアヌキテクチャに぀いお挠然ずほのめかした。 ヒントから、デスクトップ䞊のItaniumが私たちを埅っおいるこずを理解するこずができたした。 ちなみに、Microsoft Windowsぞの移怍ずItanium甚のVisual C ++コンパむラもこれを間接的に蚌蚀しおいたす誰もがitaniumでWindowsが動䜜しおいるのを芋たこずがありたすか Itaniumはサヌバヌセグメントにずどたり、開発のための適切なリ゜ヌスを取埗できず、ゆっくりず死にかけおいたした。
䞀方、「非垞に長い呜什語」VLIW-非垞に長い呜什語の呜什の「束」を持぀Itaniumは、䟝然ずしお興味深く画期的なプロセッサです。 Itaniumでは、最新のプロセッサ自䜓が実行するもの-実行ナニットをロヌドし、操䜜を䞊べ替える-はコンパむラに委ねられたした。 しかし、コンパむラヌはそのようなタスクに察凊できず、最適なコヌドではない生成および生成を行うこずができたせんでした。 その結果、Itaniumのパフォヌマンスは数回䜎䞋したした。そしお、VLIWの「バンドル」に関する指瀺の䞍合理なItaniumの芳点からの配垃のみによりItaniumで䜕ず呌ばれおいるのか芚えおいたせんが、翻蚳-「バンドル」は蚘憶されおいたした実行ブロックの䞍合理なロヌド。
Itanium – .
, , , ?..


Happens-before, synchronized-with


, C++11, : « , , — happened before, synchronized-with ?»
– .
C++ Concurrency in Action ( ), . .
– () C++, , . C++.
, , memory_order - lock-free . sequential consistency – - memory_order - . , .
– acquire/release relaxed – .

UPD: cheremin . , sequential consistency , — . : lock-free , , — .


lock-free


— relacy . , . , lock-free relacy ( ? – , , , ). , , memory_order -, production- . lock-free , — , . , . ( «» – , , - ) ( ), — , .
, relacy, , ( – relacy ), Intel – , (relacy - ) . . - safe iterators STL.
Google ThreadSanitizer . data race ( ) , , , . , STL, — (Clang 3.2, GCC 4.8 ).
ThreadSanitizer – , — . libcds , , libcds .
x86
x86, , (weakly-ordered) . , lock-free : , x86, .
, memory_order - null ( nop!), — x86 . , release- – mov , mov relaxed-.
lock-free , , x86- - .


« ...» —


, C++11! , , . - :
 template <typename T> class atomic { template <memory_order Order = memory_order_seq_cst> T load() const ; template <memory_order Order = memory_order_seq_cst> void store( T val ) ; template <memory_order SuccessOrder = memory_order_seq_cst> bool compare_exchange_weak( T& expected, T desired ) ; //    }; 

, , .
, , . [] . , , (, , , release- ). . , :
 extern std::memory_order currentOrder ; std::Atomic<unsigned int> atomicInt ; atomicInt.store( 42, currentOrder ) ; 

C++11. , , , :

. memory_order . , :
 std::Atomic<int> atomicInt ; atomicInt.store<std::memory_order_release>( 42 ) ; //   : atomicInt.template store<std::memory_order_release>( 42 ) ; 

, , «» , — .
C++11 , , — C. std::atomic C++11 C- atomic_load , atomic_store .
, libcds , C++11 , . , - , libcds C++11.


– .

« ». , - 


“ ” – lock-free .

Source: https://habr.com/ru/post/J197520/


All Articles