GNU C++ のアトミック スワップ
-
21-09-2019 - |
質問
私の理解が正しいかどうかを確認したいです。この種のことは難しいので、何かが欠けているとほぼ確信しています。リアルタイム スレッドと非リアルタイム スレッドで構成されるプログラムがあります。非 RT スレッドが、RT スレッドによって使用されるメモリへのポインタを交換できるようにしたいと考えています。
ドキュメントによると、これは次の方法で実現できると理解しています。 g++
と:
// global
Data *rt_data;
Data *swap_data(Data *new_data)
{
#ifdef __GNUC__
// Atomic pointer swap.
Data *old_d = __sync_lock_test_and_set(&rt_data, new_data);
#else
// Non-atomic, cross your fingers.
Data *old_d = rt_data;
rt_data = new_data;
#endif
return old_d;
}
これは、プログラム内で (初期セットアップを除く) 唯一の場所です。 rt_data
変更されます。いつ rt_data
リアルタイム コンテキストで使用されると、ローカル ポインターにコピーされます。のために old_d
, 、後で古いメモリが使用されていないことが確実になったときに、非 RT スレッドで解放されます。これは正しいです?必要ですか volatile
どこでも?他に呼び出す必要のある同期プリミティブはありますか?
ちなみに、私はこれを C++ でやっていますが、C では答えが異なるかどうかに興味があります。
よろしくお願いします。
解決
通常は使用しません volatile
同時実行コードを記述するとき C/C++
. 。のセマンティクス volatile
自分の望むものにとても近いので、誘惑に駆られますが、最終的には不安定です。 足りない. 。残念ながら Java/C# volatile != C/C++ volatile
. 。ハーブ・サッターには優れた機能があります 記事 混乱を招く混乱を説明する。
本当に欲しいのはメモリフェンスです。 __sync_lock_test_and_set
フェンスを提供します。
rt_data ポインタをローカル コピーにコピー (ロード) するときにもメモリ フェンスが必要になります。
ロックフリーのプログラミングは難しいです。Gcc の c++0x 拡張機能を使用したい場合は、もう少し簡単です。
#include <cstdatomic>
std::atomic<Data*> rt_data;
Data* swap_data( Data* new_data )
{
Data* old_data = rt_data.exchange(new_data);
assert( old_data != new_data );
return old_data;
}
void use_data( )
{
Data* local = rt_data.load();
/* ... */
}
他のヒント
更新:この答えは正しくありません、私のこと volatile
ることを保証へのアクセス volatile
変数は注文での提供等の保証に関してその他の非volatile
アクセスの操作.メモリのフェンスが提供などの保証が必要です。私の答えが以下で行動しないことです。見 この答え い説明についての穴もに以下のような応答を返す。
独自の回答:
ありが必要 volatile
ご rt_data
宣言 時間変数の変更ができる外部制御の流れのスレッドにアクセスで宣言されたすべき volatile
.なることができるかな volatile
からだのコピーカルポインタ volatile
少なくとも手伝書類のものを抑制するいくつかのコンパイラの最適化を引き起こすことが可能な課題です。次の例を考えてみてください採択されたから DDJ:
volatile int a;
int b;
a = 1;
b = a;
であれば可能 a
してその値が変更されたと a=1
や b=a
, その a
うに宣言され volatile
(ない場合はもちろん、提供しなければならない日付の値を b
することも可能です。Multithreading、特に原子のプリミティブを構成し、そのの状況も起変数の変更による信号ハンドラによる変数にマッピングされ奇数のメモリ場所(例:ハードウェアI/Oレジスタ).参照 この質問.
そうでない場合は、見晴しい。
Cのように使用原子のプリミティブの提供 GLib ます。彼らはそれを使用する原子操作が可能と低遅れが正しいミューテックスによる実装の場合、原子操作はできません。向があるものを提供し同様のC++.