これについての詳細を探してみました。mutex とアトミックに関する標準も読みましたが、それでも C++11 メモリ モデルの可視性の保証を理解できませんでした。私が理解していることから、ミューテックス BESIDE 相互排除の非常に重要な機能は、可視性を確保することです。また、一度に 1 つのスレッドだけがカウンターを増加させるだけでは十分ではありません。最後にミューテックスを使用したスレッドによって格納されたカウンターをスレッドが増加させることが重要です (議論するときに人々がこれについてこれ以上言及しない理由が本当にわかりませんミューテックス、多分私は悪い教師を持っていました:))。したがって、私が言えることから、アトミックは即時の可視性を強制しません: (boost::thread を維持し、c++11 スレッドとミューテックス ライブラリを実装した人から):
memory_order_seq_cst を使用したフェンスは、他のスレッドへの即時の可視性を強制しません (MFENCE 命令も同様です)。C++0x メモリの順序付け制約は、まさにそれです --- 順序付け制約です。memory_order_seq_cst 操作は全体の順序を形成しますが、すべてのスレッドで合意する必要があることと、他の順序制約に違反してはならないことを除いて、その順序に制限はありません。特に、スレッドが制約と一致する順序で値を参照する場合、スレッドはしばらくの間「古い」値を参照し続ける可能性があります。
そして、私はそれで大丈夫です。しかし、問題は、アトミックに関する C++11 の構造が「グローバル」であり、アトミック変数の一貫性のみを保証するものを理解するのに苦労していることです。特に、ロードとストアの前後にメモリフェンスが存在することを保証する次のメモリ順序のどれが(もしあれば)理解しています: http://www.stdthread.co.uk/doc/headers/atomic/memory_order. html
私が言えることから、 std::memory_order_seq_cst はメモリバリアを挿入しますが、他のものは特定のメモリ位置での操作の順序付けのみを強制します。
だから誰かがこれを片付けることができますか、多くの人が std::atomic を使用して恐ろしいバグを作っていると思います.espは、デフォルトを使用しない場合(std::memory_order_seq_cstメモリ順序付け)
2.私が正しければ、それはそれを意味しますこのコードでは、2 行目は冗長です。
atomicVar.store(42);
std::atomic_thread_fence(std::memory_order_seq_cst);
3. do std::atomic_thread_fence には、非アトミック var で seq の一貫性を確保するために std::atomic_thread_fence(std::memory_order_seq_cst); を実行する必要があるという意味で、ミューテックスと同じ要件があります。ロード前と std::atomic_thread_fence(std::memory_order_seq_cst);
アフターストア?
4.は
{
regularSum+=atomicVar.load();
regularVar1++;
regularVar2++;
}
//...
{
regularVar1++;
regularVar2++;
atomicVar.store(74656);
}
に相当
std::mutex mtx;
{
std::unique_lock<std::mutex> ul(mtx);
sum+=nowRegularVar;
regularVar++;
regularVar2++;
}
//..
{
std::unique_lock<std::mutex> ul(mtx);
regularVar1++;
regularVar2++;
nowRegularVar=(74656);
}
ないと思いますが、確認したいと思います。
編集: 5.発砲をアサートできますか?
2 つのスレッドのみが存在します。
atomic<int*> p=nullptr;
最初のスレッドの書き込み
{
nonatomic_p=(int*) malloc(16*1024*sizeof(int));
for(int i=0;i<16*1024;++i)
nonatomic_p[i]=42;
p=nonatomic;
}
2 番目のスレッドの読み取り
{
while (p==nullptr)
{
}
assert(p[1234]==42);//1234-random idx in array
}