인프런 강의 를 듣고, 개인 공부 목적으로 정리한 글입니다.
https://velog.io/@xiniha/Race-Condition과-Data-Race-알아보기
https://learn.microsoft.com/ko-kr/dotnet/api/system.threading.interlocked?view=net-7.0
명령어를 병렬적으로 실행할 때, 명령어 실행 순서에 따라 다른 결과를 나타낼 수 있는 상황을 의미한다.
즉, 순서가 결과에 영향을 미치는 상황 자체를 의미한다.
겜서버 수업에서 배웠던 DataRace 또한 RaceCondition에 포함된다.
Data Race
같은 메모리를 한 개 이상의 쓰레드가 동시에 읽고 쓰는 경우,
내가 사용하는 메모리의 내용이 내가 아닌 다른 쓰레드에 의해 변경될 수 있다.
즉, 멀티쓰레드 환경에서 데이터가 다른 쓰레드의 명령어에 의해 변경될 수 있다.
이러한 Race Condition을 막을 수 있는 방법 중 하나가 Interlocked이다.
이러한 Race Condition 상황을 막아주는 방법인데,
상호 배제(Mutex) 라고 생각하면 될 것 같다.
기본적으로
자원 res를 A가 사용하고 있으면 B는 res에 접근하지 못한다.
.NET 에서 제공하는 클래스로,
멀티쓰레드 환경에서 특정 변수의 Atomic한 동작을 보장한다.
Atomic (원자성)
Atomic하게 동작한다
== 동작을 더 이상 쪼개면 안된다Do or Not
0 or 1
동작을 하거나 / 안하거나.
하다 마는건 없다.
중간 과정은 없다.실행하기 시작했으면 해당 동작이 끝날 때까지 기다려야 한다.
Interlocked 계열의 함수를 사용하면 Atomic한 동작이 보장된다.
어쨌든,.. 멀티쓰레드 환경에서 어떠한 동작이 먼저 일어날 수 밖에 없지만, 그 결과는 무조건 Atomic하게 보장된다.
그리고..
참고로
Interlocked하면 내부에서 Memory Barrier을 간접적으로 사용하고 있으므로 volatile은 사용하지 않아도 된당.
또한 참고로
Interlocked는 내부적으로 Lock을 통해 동작한다
Interlocked.Increment()
: 증가
Interlocked.Decrement()
: 감소
함수 내부에 인자를 넣을 때는 ref number
의 식으로 레퍼런스로 넘겨준다.
(Atomic하게 동작하는게 기본이므로 주소값을 넘겨줘야 한다)
둘 이상의 작업이 서로가 끝날 때까지 영원히 기다리는 상황
(혹시 그림이 잘못 그려졌다면 알려주시면 감사하겠습니다)
사용중 == 점유 (lock)
쓰레드 1, 쓰레드 2, 자원 1, 자원 2
쓰레드 1 : 자원 1 점유중, 자원 2 필요
쓰레드 2 : 자원 2 점유중, 자원 1 필요
이러한 상황인 경우에,
각각의 쓰레드는 자원을 하나씩 점유(lock)하고 있어서 다른 쓰레드에서 해당 자원에 접근이 불가능하다.
하지만.. 해당 자원이 필요하니까
각각의 점유(lock)가 풀릴 때까지 무한정 기다리면서.. 무한대기 상태에 빠지게 된다