bdfgdfg

Interlocked 본문

게임프로그래밍/C#

Interlocked

marmelo12 2022. 12. 13. 23:11
반응형

C++에도 있는거.

 

멀티쓰레드 환경에서 원자적으로 처리를 위해 사용한다.

 

내부적으로 다양한 것들이 있지만 중요하다 생각하는 것. Interlocked.CompareExchange

즉 비교와 교환을 원자적으로 처리한다.

 

밑의 코드가 있다고 생각해보자.

void ExpireQuest()
{
    if(Quest.bAlive == true)
    {
        Quest.bAlive = false;
    }
}

어떤 퀘스트가 있고, 퀘스트 객체는 만료날짜를 넘어갔기에 해당 퀘스트를 닫아줘야 하는 코드.

 

만약 멀티쓰레드 환경에서 저 코드가 실행된다고 보자.

A,B쓰레드가 있고 A와 B쓰레드는 저 Quest라는 객체에 동시에 접근하는 상황.

 

A쓰레드는 if문의 Quest.bAlive가 true인것을 확인하고 해당 Quest의 멤버인 bAlive를 false로 바꾸려고한다.

이 때 A쓰레드는 컨텍스트 스위칭으로 인해 bAlive를 false로 바꾸지못하고 B쓰레드로 전환이 된다.

B쓰레드는 A쓰레드가 bAlive를 false로 바꾸지 않았기에 A쓰레드와 동일하게 bAlive가 true인것을 확인하고 bAlive에 false를 대입한다.

 

위 예제에는 결국엔 경합이 일어나건 말건 bAlive의 상태를 false로 바꾼다는 결과는 같으니 상관없어 보일 수 있지만.. 결국 경합이 일어난다는 점에서 문제가 발생할 위험성이 높다.

 

즉 이러한 경우에서. 비교와 교환을 원자적으로 처리할 수 있는 Interlocked.CompareExchange를 사용하면 좋다.

void ExpireQuest_ThreadSafe()
{
    if( Interlocked.CompareExchange(ref m_iLockVar, 1, 0 ) != 0 )
    {
      return;
    }
    
    Quest.bAlive = false;
    Interlocked.Decrement( ref m_iLockVar );
}

 

Interlocked.CompareExchange( ref A,B,C )

 

여기서 인자의 A와 C의 값이 같은지를 비교하고, 같다면 A의 값을 B로 바꾼 후 A의 원래 값을 반환한다.

 -> A가 0이었고 Interlocked.CompareExchange( ref A,1,0 ) 이라고 할 때 A는 1로 바뀌며 이 함수의 반환값은 0이된다.

 

만약 A와 C가 같지않으면 A값은 바꾸지 않고 그대로 A의 값을 반환한다.

반응형

'게임프로그래밍 > C#' 카테고리의 다른 글

Linq - Group by  (0) 2022.11.05
[C#] 예외처리(try-catch)  (0) 2022.04.22
[C#] 일반화(제네릭) 프로그래밍  (0) 2022.04.21
[C#] 인덱서(Indexer)  (0) 2022.04.21
[C#] 프로퍼티(갓)  (0) 2022.04.19
Comments