enable = true
を設定する必要がある場合は、リリース/取得オーダーを使用してstdatomic.h
を入力してください。 (x86 asmでは、通常のストア/ロードにはセマンティクスがリリース/取得されているので、コンパイル時の並べ替えをブロックするだけで十分ですが、ではなくatomic
を使用するのが正しい方法です。)
しかし、あなたは、あなたがそれを変更しながら、再び「ロックアウト」の読者にenable = false
を設定することができるようにしたい場合は、より複雑な更新パターンが必要です。アトミックで手動でミューテックスを再現するか(悪いアイデア;それの代わりに標準ライブラリミューテックスを使用する)、更新の途中でライターがいないときに複数のリーダーによる待機なしの読み取り専用アクセスを可能にするものを実行します。
RCUaまたはseqlockのいずれかが良い場合はとなります。
seqlockの場合、enable = true/falseフラグの代わりに、シーケンス番号があります。リーダは、他のメンバーを読み取った後にシーケンス番号を確認し、その後にもう一度チェックすることによって、「破れた」書き込みを検出することができる。 (しかし、すべてのメンバーは少なくともmo_relaxed
を使用してatomic
でなければなりません。それ以外の場合は、値を破棄してもCで読み取られたデータの競合が未定義のデータ競合となります。おそらく最初のもので取得してから、shared_struct->b
の負荷で取得して、シーケンス番号の2番目の負荷がそれ以降に注文されることを確認してください(acquire
は一方通行の障壁に過ぎません。あなたが必要とするもの)
RCUは、読者が常に完全に待ち時間をなくし、現在有効な構造体へのポインタを逆参照するだけです。あなたはすべてのリーダースレッドがmemブロックを読み終えていることを確認しなければなりませんあなたがそれを再使用する前にオーディー。
は単に作家がそれらを変更している間に、他のメンバーのために一貫性のない/部分的に更新された値を見て、その後enable == true
を見てからリーダーを停止していない他の構造体のメンバーを変更し、前enable = false
を設定します。これを行う必要はなく、他のスレッドがアクセスするために新しいオブジェクトを解放するだけの場合は、記述するシーケンスはatomic_store_explicit(&foo->enable, true, memory_order_release)
で問題ありません。
これはまったくありません。アトミックフラグがある場合は、C11 ' ' –
を使用してください。これは、揮発性のアクセスが並べ替えられない「副産物」です。 – filo
@AnttiHaapalaアトミックアクセスは命令の並べ替えと何が関係していますか? – Lundin