C#

C# 멀티스레드 동기화 : Monitor.Enter, Monitor.Exit

우준세 2024. 2. 19. 16:47
728x90
반응형

 

 

이번 포스팅은 C#으로 프로젝트를 진행하면서 알게 된 
Monitor.Enter 메서드와 Monitor.Exit 메서드에 대해 정리하였습니다.


멀티스레드 환경으로 프로젝트를 진행하다 보면

여러 스레드가 객체에 동시에 접근하게 되어 에러가 발생하는 경우가 있습니다.

 

이런 에러를 방지하기 위해 C#에서 Monitor.Enter 및 Monitor.Exit 메서드를 사용하여

잠금(locking)을 제공하여 여러 스레드가 동시에 접근하지 못하도록 보호합니다.

 

| Monitor.Enter

'Monitor.Enter' 메서드는 특정 객체에 대한 잠금을 요청하고, 이 잠금을 획득할 때까지 대기합니다. 

만약 이미 다른 스레드가 해당 객체에 대한 잠금을 하고 있다면,

현재 스레드는 잠금을 할 수 있을 때까지 멈추고 대기합니다. 

 

| Monitor.Exit

'Monitor.Exit' 메서드는 특정 객체에 대한 잠금을 해제합니다.

잠금을 해제한다는 뜻은 해당 객체를 다시 다른 스레드가 접근할 수 있도록 허용한다는 뜻입니다.

이때, 잠금을 보유하고 있지 않은 객체에 대해 'Monitor.Exit' 메서드를 호출하면 예외가 발생할 수 있습니다.

 

| 코드 예시

static List<int> sharedList = new List<int>(); // 공유 자원인 리스트

static void Main(string[] args)
{
	// 여러 개의 스레드를 생성하여 리스트에 값을 추가하는 작업 수행
	for (int i = 0; i < 5; i++)
	{
		Thread thread = new Thread(AddToList);
		thread.Start(i);
	}

	Console.ReadLine();
}

static void AddToList(object id)
{
	int threadId = (int)id;

	// 리스트에 접근하기 전에 잠금을 획득
	Monitor.Enter(sharedList);

	try
	{
		Console.WriteLine($"Thread {threadId} is adding to the list...");
		sharedList.Add(threadId);
		Console.WriteLine($"Thread {threadId} added to the list.");
	}
	finally
	{
		// 작업이 완료되면 잠금을 해제
		Monitor.Exit(sharedList);
	}
}

 

우선 'Monitor,Enter' 와 'Monitor.Exit'를 사용하여 잠금을 관리할 때,

'try - finally' 블록을 사용하여 예외 발생 시 항상 잠금이 해제되도록 하는 것이 좋습니다.

잠금을 한 후에는 반드시 해제되어야 하기 때문입니다. 

 

위 코드는 여러 스레드가 동시에 'sharedList'라는 리스트에 접근하고 값을 추가하는 간단한 코드 에제입니다. 

각 스레드는 'AddToList' 메서드를 호출하여 리스트에 값을 추가합니다.

 

'Monitor,Enter' 와 'Monitor.Exit' 를 사용하여 리스트에 접근하기 전에 잠금을 하고 

작업을 완료한 후에 잠금을 해제합니다. 

이렇게 함으로써 여러 스레드가 동시에 리스트에 접근할 때 데이터 일관성과 안전을 보장합니다.


| 마무리 

'Monitor,Enter' 와 'Monitor.Exit' 메서드는 동기화 기법의 일종입니다.

동기화를 사용하여 여러 스레드가 공유하는 자원에 대해 안전하게 작업할 수 있도록 보장하는 것입니다.

이는 데이터의 일관성과 안전성을 높이는데 도움이 됩니다.

 

그러나 동기화 기법을 너무 많이 사용하면 성능 저하가 발생할 수 있으므로,

잠금이 필요한 부분을 최소화하고 데드락을 피하는 것이 더 중요하다고 생각합니다.

 

틀린 점이나 질문이 있으시면 댓글로 남겨주세요!

 

 

감사합니다 :)

 

728x90
반응형