C #에서 bool 필드 원자에 액세스하고 있습니까? 특히, 나는 주위에 자물쇠를 두어야합니까?
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 및 reference 유형과 같은 데이터 유형의 읽기 및 쓰기는 원자 적입니다.
에서 발견 C # 언어 사양 .
편집 : 휘발성 키워드를 이해하는 것도 가치가있을 것입니다 .
답변
위에서 언급했듯이 bool은 원자 적이지만 여전히 원하는 작업에 따라 달라진다는 점을 기억해야합니다.
if(b == false)
{
//do something
}
원자 연산이 아니므로 현재 스레드가 if 문 다음에 코드를 실행하기 전에 b 값이 변경 될 수 있습니다.
답변
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에 적절할 것이라고 생각 합니다.