Thread
-
스레드 생성 시 반복문의 인덱스를 매개변수로 받을 때
스레드(Thread)를 생성할 때, 반복문으로 여러 개의 스레드를 생성하면서 그 반복문의 인덱스를 매개변수로 전달하는 방법을 쓸 때가 있다.
class ThreadTestProgram
{
public static int DeviceNum = 10;
public static void Main(string[] args)
{
for (int i = 0; i < DeviceNum; i++)
{
new Thread(() => Run(i)).Start();
}
}
public static void Run(int idx)
{
// 디바이스 인덱스에 따라서 스레드 별로 각 디바이스와 연결하는 작업...
Console.WriteLine(idx);
}
}
위의 예시 코드가 바로 그것이다. 여러 개의 디바이스에 연결해서 스레드로 작업을 처리해야 할 때의 코드인데, 스레드 함수에서는 반복문에서 디바이스의 인덱스를 전달받아서 연결하도록 설계된 코드이다.
물론 스레드이기 때문에 실행 순서 자체는 보장할 수 없지만, 적어도 각 스레드가 매개변수의 값으로 0, 1, 2, 3, 4, 5, 6, 7, 8, 9를 전달받는 것을 기대하고 설계된 코드라고 볼 수 있다.
하지만 실행결과를 보면 각 스레드가 전달받은 매개변수 값은 1, 2, 3, 4, 5, 5, 6, 8, 8, 10으로 0, 7, 9를 전달받은 스레드는 없고 5와 8을 전달받은 스레드는 두 개씩 있는 엉망진창인 상태인 것을 볼 수 있다.
이 상황이 의미하는 것은 스레드의 매개변수로 넣은 반복문의 인덱스 값이 스레드가 시작되기 전에 변경되면 스레드의 매개변수 값 역시 영향을 받는다는 것이다.
// int i = 0 -> 반복문에 사용될 인덱스 값 설정
for(int i = 0; i < DeviceNum; i++)
{// i < DeviceNum -> 인덱스 값이 반복문 내의 코드 블럭을 실행하기에 유효한지 검사
new Thread(() => Run(i)).Start(); // 스레드 생성
// i 값이 증가하기 전에 스레드가 시작되면 원래 값이 들어간다.
}// i++ 값 증가 // i 값이 증가한 이후에 스레드가 시작되면 i + 1 값이 들어간다.
각 코드 진행 상황에 대한 해설을 달자면 위와 같다. i값이 증가한 이후에 스레드가 시작되는 것이 문제로 스레드가 시작되기 전까지 전달되는 값이 변하지 않을 것에 대한 보장이 필요한 상태이다.
이를 위해서 코드를 다음과 같이 변경해보자.
class ThreadTestProgram
{
public static int DeviceNum = 10;
public static void Main(string[] args)
{
for (int i = 0; i < DeviceNum; i++)
{
int idx = i; // i 값이 바뀌어도 상관없도록 임시 변수에 값을 전달하여 스레드의 매개 변수로 사용new Thread(() => Run(idx)).Start();
}
}
public static void Run(int idx)
{
// 디바이스 인덱스에 따라서 스레드 별로 각 디바이스와 연결하는 작업...
Console.WriteLine(idx);
}
}
위의 임시 코드처럼 i의 값을 임시 변수에 전달해서 스레드에 매개변수로 전달하면 i값이 증가해도 idx의 값은 증가하지 않기 때문에 스레드가 실행될 때까지 값이 변조되지 않을 것이다.
실제로 코드를 컴파일해보면 실행순서는 섞여있지만 각 스레드가 디바이스 인덱스로 0, 1, 2, 3, 4, 5, 6, 7, 8, 9를 받은 것을 확인할 수 있다.
[유니티 어필리에이트 프로그램]
아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.
[투네이션]
[Patreon]
[디스코드 채널]
'C#' 카테고리의 다른 글
[C#] enum (0) | 2022.02.03 |
---|---|
[C#] foreach - 배열과 컬렉션를 위한 반복문 (0) | 2019.10.27 |
[C#] Thread - 여러 작업을 동시 처리하기 (2) | 2019.10.25 |
[C#] static - 정적 변수와 정적 함수 그리고 정적 클래스 (0) | 2019.09.18 |
[C#] Attribute : Obsolete - 더 이상 사용하지 않거나 그럴 예정인 코드에 대해서 (2) | 2017.01.21 |