Computer >> 컴퓨터 >  >> 프로그래밍 >> C#

C#에서 배열에 대한 동기화된 액세스를 얻는 방법

멀티스레드 환경에서 여러 스레드가 동시에 하나의 배열에 접근하면 데이터 불일치나 예기치 않은 오류가 발생할 수 있습니다. 이를 방지하려면 lock 문과 SyncRoot 속성을 사용하여 배열에 대한 동기화된(스레드 안전한) 액세스를 구현해야 합니다.

동기화 액세스란?

동기화 액세스란 한 시점에 하나의 스레드만 배열에 접근할 수 있도록 잠금(lock)을 거는 것을 의미합니다. C#의 Array 클래스가 제공하는 SyncRoot 속성은 컬렉션에 대한 동기화에 사용되는 객체를 반환하며, 이 객체를 lock 블록으로 감싸면 해당 코드 영역은 한 번에 하나의 스레드만 실행할 수 있습니다.

예제 1: 정수형 배열 동기화

다음은 정수형 배열에 lock을 적용하여 동기화된 액세스를 수행하는 예제입니다.

using System;
public class Demo {
   public static void Main() {
      Array intArr = new int[] {5, 10, 15, 20, 25, 30, 35, 40 };
      Console.WriteLine("정수형 배열...");
      foreach (int i in intArr)
      Console.WriteLine(i);
      Console.WriteLine("배열에 lock 적용 후...");
      lock(intArr.SyncRoot) {
         foreach (Object ob in intArr)
         Console.WriteLine(ob);
      }
   }
}

출력 결과

위 코드를 실행하면 다음과 같은 결과가 출력됩니다.

정수형 배열...
5
10
15
20
25
30
35
40
배열에 lock 적용 후...
5
10
15
20
25
30
35
40

예제 2: 문자열 배열 동기화

이번에는 문자열 배열에 동일한 방식으로 lock을 적용해 보겠습니다.

using System;
public class Demo {
   public static void Main() {
      Array strArr = new String[] {"Harry", "Tom", "Kevin", "Ryan", "Katie", "Amy" };
      Console.WriteLine("문자열 배열...");
      foreach (string i in strArr)
      Console.WriteLine(i);
      Console.WriteLine("배열에 lock 적용 후...");
      lock(strArr.SyncRoot) {
         foreach (Object ob in strArr)
         Console.WriteLine(ob);
      }
   }
}

출력 결과

실행 결과는 다음과 같습니다.

문자열 배열...
Harry
Tom
Kevin
Ryan
Katie
Amy
배열에 lock 적용 후...
Harry
Tom
Kevin
Ryan
Katie
Amy

핵심 정리

Array.SyncRoot 속성은 배열 자체에 대한 동기화 잠금에 사용되는 객체를 반환합니다. lock(SyncRoot) 블록 내부의 코드는 한 번에 하나의 스레드만 실행할 수 있으므로, 멀티스레드 환경에서 배열을 안전하게 읽거나 수정할 때 유용합니다. 단, SyncRoot는 잠금 메커니즘만 제공할 뿐 배열 자체를 자동으로 보호해 주지는 않으므로, 배열에 접근하는 모든 코드에서 반드시 동일한 SyncRoot 객체로 lock을 걸어야 합니다.