C #에서 bool 필드 원자에 액세스하고 있습니까? 특히, 나는 주위에 자물쇠를 두어야합니까?
class Foo
{
private bool _bar;
//... in some function on any thread (or many threads)
_bar = true;
//... same for a read
if (_bar) { ... }
}
C #에서 bool 필드 원자에 액세스하고 있습니까? 특히, 나는 주위에 자물쇠를 두어야합니까?
class Foo
{
private bool _bar;
//... in some function on any thread (or many threads)
_bar = true;
//... same for a read
if (_bar) { ... }
}
답변:
Interlocked.Add(ref myInt);
적이 라면 언제 사용 합니까?
i++
는 i=i+1
원자 읽기, 덧셈, 원자 쓰기를 수행함을 의미합니다. 다른 스레드 i
는 읽기 후 쓰기 전에 수정할 수 있습니다. 예를 들어 i++
동일한 i 에서 동시에 수행하는 두 개의 스레드는 동시에 읽을 수 있으며 (따라서 동일한 값을 읽음) 하나를 추가 한 다음 둘 다 동일한 값을 작성하여 효과적으로 한 번만 추가 할 수 있습니다. Interlocked.Add는 이것을 방지합니다. 일반적으로 유형이 원자 적이라는 사실은 쓰기 스레드가 하나 뿐이고 읽기 스레드가 많은 경우에만 유용합니다.
bool 액세스는 실제로 원자 적이지만 이것이 전체 이야기는 아닙니다.
'불완전하게 쓰여진'값을 읽는 것에 대해 걱정할 필요가 없습니다. 어떤 경우 에든 부울에 대해 의미 할 수있는 것이 무엇인지 명확하지 않습니다.하지만 적어도 다음과 같은 세부 정보가 있다면 프로세서 캐시에 대해 걱정해야합니다. 타이밍이 문제입니다. 코어 A에서 실행중인 스레드 # 1 _bar
에 캐시가 있고 _bar
다른 코어에서 실행중인 스레드 # 2에 의해 업데이트되는 경우, 스레드 # 1은 잠금을 추가 하거나 _bar
로 선언 volatile
하거나 명시 적으로 호출을 삽입 하지 않는 한 변경 사항을 즉시 볼 수 없습니다 Thread.MemoryBarrier()
. 캐시 된 값.
var fatObject = new FatObject(); Thread.MemoryBarrier(); _sharedRefToFat = fatObject;
내가 사용한 접근 방식이 정확하다고 생각합니다.
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에 적절할 것이라고 생각 합니다.
lock()
, 당신은 필요하지 않습니다 volatile
.