데드락(Deadlock)은 동시성 프로그래밍에서 발생할 수 있는 심각한 문제입니다. 데드락이 발생하면 프로그램이 영원히 실행되지 않는 상태에 빠지게 되므로, 이에 대한 이해와 해결 방법을 숙지하는 것이 중요합니다.
데드락이란?
데드락은 두 개 이상의 스레드가 서로 다른 리소스를 점유하고 있는 상태에서, 서로가 상대방이 점유한 리소스를 요구하면서 발생하는 교착 상태를 말합니다.
예를 들어, 스레드 A가 리소스 X를 점유하고 있고, 스레드 B가 리소스 Y를 점유하고 있는데, 스레드 A가 리소스 Y를 요구하고, 스레드 B가 리소스 X를 요구하는 경우 데드락이 발생합니다. 이 상황에서 두 스레드는 서로의 리소스를 기다리게 되어 교착 상태에 빠지게 됩니다.
lock
키워드 사용과 데드락
lock
키워드는 C#에서 스레드 간 동기화를 위해 널리 사용되는 방법입니다. 하지만 lock
키워드를 잘못 사용하면 데드락이 발생할 수 있습니다.
예를 들어, 두 개의 메서드에서 서로 다른 순서로 두 개의 lock
객체를 사용한다면 데드락이 발생할 수 있습니다. 이 경우 리소스 사용 순서를 일관성 있게 유지하는 것이 중요합니다.
Monitor 클래스를 활용한 데드락 해결
데드락 문제를 해결하기 위해서는 리소스 사용 순서를 일관성 있게 유지하는 것이 중요합니다. 이를 위해 Monitor
클래스를 활용할 수 있습니다.
public class SharedResource
{
private object lockObject1 = new object();
private object lockObject2 = new object();
public void MethodA()
{
Monitor.Enter(lockObject1);
try
{
Thread.Sleep(1000); // 의도적으로 지연
Monitor.Enter(lockObject2);
try
{
Console.WriteLine("MethodA is executed.");
}
finally
{
Monitor.Exit(lockObject2);
}
}
finally
{
Monitor.Exit(lockObject1);
}
}
public void MethodB()
{
Monitor.Enter(lockObject2);
try
{
Thread.Sleep(1000); // 의도적으로 지연
Monitor.Enter(lockObject1);
try
{
Console.WriteLine("MethodB is executed.");
}
finally
{
Monitor.Exit(lockObject1);
}
}
finally
{
Monitor.Exit(lockObject2);
}
}
}
위 코드에서는 Monitor.Enter()
와 Monitor.Exit()
를 사용하여 리소스 사용 순서를 일관성 있게 유지하고 있습니다. 이를 통해 데드락 문제를 해결할 수 있습니다.
Mutex 클래스를 활용한 데드락 해결
데드락 문제를 해결하는 또 다른 방법은 Mutex
클래스를 사용하는 것입니다. Mutex
는 전역 리소스에 대한 상호 배제를 제공하므로, 데드락 문제를 방지할 수 있습니다.
public class SharedResource
{
private Mutex mutex1 = new Mutex();
private Mutex mutex2 = new Mutex();
public void MethodA()
{
mutex1.WaitOne();
try
{
Thread.Sleep(1000); // 의도적으로 지연
mutex2.WaitOne();
try
{
Console.WriteLine("MethodA is executed.");
}
finally
{
mutex2.ReleaseMutex();
}
}
finally
{
mutex1.ReleaseMutex();
}
}
public void MethodB()
{
mutex2.WaitOne();
try
{
Thread.Sleep(1000); // 의도적으로 지연
mutex1.WaitOne();
try
{
Console.WriteLine("MethodB is executed.");
}
finally
{
mutex1.ReleaseMutex();
}
}
finally
{
mutex2.ReleaseMutex();
}
}
}
public static void Main(string[] args)
{
var resource = new SharedResource();
// 두 개의 스레드를 생성하여 MethodA와 MethodB를 호출
Thread threadA = new Thread(resource.MethodA);
Thread threadB = new Thread(resource.MethodB);
threadA.Start();
threadB.Start();
threadA.Join();
threadB.Join();
}
위 코드에서는 Mutex 클래스를 사용하여 리소스 사용 순서를 일관성 있게 유지하고 있습니다. Mutex.WaitOne()을 통해 리소스를 점유하고, Mutex.ReleaseMutex()를 통해 리소스를 해제합니다. 이를 통해 데드락 문제를 해결할 수 있습니다.
데드락 문제는 동시성 프로그래밍에서 발생할 수 있는 중요한 문제이므로, 이를 예방하고 해결할 수 있는 방법을 숙지해 두는 것이 중요합니다. lock 키워드, Monitor 클래스, Mutex 클래스 등을 활용하여 데드락 문제를 해결할 수 있습니다.
'C#' 카테고리의 다른 글
간단한 메서드 실행 시간 측정기 (0) | 2024.07.25 |
---|---|
C# WinForms에서 콘솔 창 띄우기 (0) | 2024.07.13 |
C# 프로그램 배포 시 소스 코드 보호하기 : 난독화와 패킹 (0) | 2024.07.11 |
Directory : 디렉토리 관리 (0) | 2024.07.09 |
Costura.Fody : 참조 DLL 라이브러리 하나로 합치기 (0) | 2024.07.08 |