◆ 무한한 가능성/& Visual C/C++

[펌글] [Thread] Mutex - 동기화

치로로 2009. 1. 12. 00:23
계속해서 Thread 간의 동기화를 위한 WaitHandle 관련 클래스를 살펴 보자.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

* WaitHandle 클래스

 

WaitHandle 클래스는 Win32에서 제공하는 Synchronization Handle 을 나타내는 추상 클래스이다.

이 추상클래스를 상속받는 클래스로는 다음과 같은 클래스가 있다.
System.Threading.WaitHandle
         System.Threading.AutoResetEvent
         System.Threading.ManualResetEvent
         System.Threading.Mutex

 
 
* Mutex 클래스

Mutex
클래스는 Thread 간의 동기화를 위한 Win32 Mutex Kernel Object 를 나타내는 클래스이다.
또한 이 Mutex 클래스는 서로 다른 Process 간의 동기화에도 사용할 수 있는 클래스이다
.
일단 Mutex 의 기본 개념에 대해 살펴 보자.

 

================================================================================================================

 

Mutual Exclusion (상호 배제)

Mutual Exclusion 란 특정 Thread 가 공유 리소스(Critical Section)를 사용하고 있을 때

다른 Thread 가 그 리소스를 사용하지 못하게 제어하는 기법이다.

, 특정 Thread 실행 시 일정한 시간 동안 하나의 리소스(Critical Section)에 대해서 전권을

가지는 것을 말한다. OS(운영체제)는 이렇게 한 리소스에 대해서 특정 시간에 한 Thread

접근할 수 있도록 Mutex를 제공한다

 

Critical Section

- 여러 Thread 에 의해 공유 및 동시에 접근,조작 했을 때 문제가 될 수 있는 부분

 

= Mutex =

뮤텍스(Mutex, mutual exclusion, 상호 배제)동시 프로그래밍에서 공유 불가능한 자원의 동시 사용을 피하기 위해 사용되는 알고리즘이다.

Critical Section 에 다수의 Thread 의 접근을 제어,관리 하는 Mutex 에는 다음과 같은 두 개의

Operation 이 있다.

a.      Acquire(취득,습득,소요) : 특정 Thread 는 공유 리소스(Critical Section) Mutex 를 소요하도록 요청한다.

     OS(운영체제)는 이 Thread 에게 소유권을 줄 수 있으면, Acquire 를 호출한 Thread 에게 Mutex에 대한 소유권을 넘긴다.
만일, 이미 다른 Thread 가 소유권을 가진 상태라면 OS 는 소유권을 줄 수 있을 때 까지
요청한 Thread Blocking 시킨다.

 

b.      Release : 특정 Thread 가 소유한 공유 리소스와 관련된 Mutex 의 소유권을 OS(운영체제)
에게 돌려 준다. OS는 이 리소스에 대한 Acquire 호출 후 Blocking 되어 있던 Thread에게
소유권을 넘긴다.

 

c.      Code Sample

MutexForX.Acquire(); // 리소스 X 에 대한 소유권을 요청한다

X.f();               // Operation f() Atomic 하게 실행된다

X.g();              // Operation g() Atomic 하게 실행된다

MutexForX.Release(); // 리소스 X 에 대한 소유권을 반납한다

=================================================================================================================

 

그럼 닷넷에서 제공하는 Mutex 클래스를 이용하여 Mutex 의 소유권을 요청하고 반납하는 것을 알아보자.

 

a)      공유 리소스에 대한 Mutex 소유권 요청.
Mutex 클래스의 생성자에 초기 소유 상태를 true 로 지정한다.
  -
Mutex mutex  = new Mutex(true,"뮤텍스 이름");
Mutex 클래스의 WaitXXX 메서드를 이용한다.
  -
mutex.WaitOne() , mutex.WaitAny() , mutex.WaitAll()

 

b)      공유 리소스에 대한 Mutex 반환(소유권 반납)
Mutex
클래스의 ReleaseMutex 메소드 이용.
-
mutex.ReleaseMutex()

 

* Demo

 

using System;

using System.Threading;

public class ThreadMutexTest

{

             public static void <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />Main()

             {

                           SharedResource sharedResource = new SharedResource();

                                                    

                           Thread thread1= new Thread(new ThreadStart(sharedResource.ThreadMethod));

                           Thread thread2= new Thread( new ThreadStart(sharedResource.ThreadMethod));

                           thread1.Start();

                           thread2.Start();

 

                           Console.WriteLine("Primary Thread 종료");

             }

}

public class SharedResource

{

             private Mutex mutex = new Mutex(false,"mutexsample");

             int count = 0;

            

             public  void ThreadMethod()

             {

                           int threadID = Thread.CurrentThread.GetHashCode();

 

                           bool isResult = mutex.WaitOne();

 

                           Console.WriteLine(String.Format("Thread {0}의 소유권 획득 유/-{1}",threadID,isResult));

                          

                           while(count < 20)

                           {

                                        if(count == 10)

                                        {

                                               //Mutex 소유권을 요청한 횟수만큼 해제 요청해야 한다.

                                               //즉 여기서는 한번만 요청했기 때문에 한번만 해제 요청해야 한다.

                                               //if(count >= 10) 조건이면 가지고 있지 않은 Mutex 를 해제하려고 한다는 Exception 발생

                                                     mutex.ReleaseMutex();

                                        }

 

                                        Console.WriteLine("Thread "+ threadID+":" + count++);

                                        Thread.Sleep(10);                                                                  

                           }                        

             }

}

 

 

Thread 중 먼저 mutex.WaitOne(); 를 호출한 Thread Mutex 소유권을 가지게 되며

소유권을 가진 Thread mutex.ReleaseMutex() 를 호출하기 전까지 다른 Thread 는 대기하게 되는 것이다.

  Mutex WaitOne ReleaseMutex 호출 사이가 임계역역이 되면 이 구간은 동기화가 보장되는 것이다.

 

= 결과 화면 =

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

* 싱글톤을 위한 Mutex

객체 생성 기법 중에서 SingleTon 이라는 생성 기법이 있다.

즉 시스템 내에서 이 클래스의 객체는 단 하나만 생성되어야 할 경우 이용하는 기법이다.

예를 들자면 윈도우 미디어 플레이어가 이 싱글톤 객체에 해당할 것이다.

Mutex 클래스를 사용하면 SingleTon 으로 객체를 생성할 수도 있다.

아래 코드는 닷넷 윈도우 프로그램의 생성자 따위에 삽입하여 이 객체는 오직 한번만 생성되도록 하는 코드 예제이다.

 

bool isFirst = true;

Mutex m = new Mutex(true,"My Mutex",out isFirst);                     

if(!isFirst)

{                     

        MessageBox.Show(this, "이미 객체가 생성되었습니다","", MessageBoxButtons.OK, MessageBoxIcon.Error);

        Application.Exit(); //강제로 Application 종료 시킨다.        

[출