C#でブールフィールドにアトミックにアクセスしていますか? 特に、ロックを設定する必要がありますか:
class Foo
{
private bool _bar;
//... in some function on any thread (or many threads)
_bar = true;
//... same for a read
if (_bar) { ... }
}
C#でブールフィールドにアトミックにアクセスしていますか? 特に、ロックを設定する必要がありますか:
class Foo
{
private bool _bar;
//... in some function on any thread (or many threads)
_bar = true;
//... same for a read
if (_bar) { ... }
}
はい。
次のデータ型の読み取りと書き込みはアトミックです: bool、char、byte、sbyte、short、ushort、uint、int、float、および参照型。
C# 言語仕様にあるように。
編集: volatileキーワードを理解することもおそらく価値があります。
上で述べたように、bool
はアトミックですが、それはあなたがそれで何をしたいかにも依存することを覚えておく必要があります。
if(b == false)
{
//do something
}
は不可分操作ではありません。つまり、現在のスレッドがステートメントb
の後にコードを実行する前に、の値が変更される可能性があります。if
bool アクセスは確かにアトミックですが、それだけではありません。
「不完全に書き込まれた」値の読み取りについて心配する必要はありません - いずれにせよ、それが bool に対して何を意味するのかは明確ではありません - しかし、少なくとも詳細がタイミングが問題。コア A で実行されているスレッド #1_bar
にキャッシュがあり、_bar
別のコアで実行されているスレッド #2 によって更新された場合、スレッド #1 は、ロックを追加するか、_bar
として宣言するvolatile
か、明示的に への呼び出しを挿入しThread.MemoryBarrier()
て、キャッシュされた値。
私が使用したアプローチは正しいと思います。
volatile bool b = false;
.. rarely signal an update with a large state change...
lock b_lock
{
b = true;
//other;
}
... another thread ...
if(b)
{
lock b_lock
{
if(b)
{
//other stuff
b = false;
}
}
}
目標は基本的に、めったに発生しない大量の状態変更情報を提供するためにオブジェクトをロックする必要があるかどうかを確認するためだけに、反復ごとにオブジェクトを繰り返しロックする必要がないようにすることでした。このアプローチは有効だと思います。また、絶対的な一貫性が必要な場合は、b bool には volatile が適切だと思います。