IT/트렌드&개념공부&TIP

동기화(Mutex, Monitor)

Andante con moto 2021. 5. 12. 05:22
728x90
반응형

1. 동기화란?

  1) 스레드(Thread)

가 자원을 공유할 때 한 번에 하나의 스레드만 사용

  2) 하나의 스레드가 공유자원을 사용할 때 공유자원에 lock을 걸어준다.

 

2. 동기화 방법

  1) lock 키워드의 사용

  2) Threading 네임스페이스의 Monitor 클래스의 사용

  3) Threading 네임스페이스의 Mutex 클래스의 사용

 

3. lock 동기화

  1) 동기화를 구현하는 키워드

  2) 동기화 객체는 참조타입이어야 함.

  3) lock 동기화와 스태틱

    - 스태틱 특성상 하나의 메모리만 만들어지기 때문에 멀티 스레드에서 스태틱에 접근하면 자동으로 스태틱은 공유자원이 된다.

 

4. 스태틱 멤버 필드를 공유자원으로 사용할 경우의 문제점

  1) 값타입 스태틱 멤버 필드에는 this를 사용할 수 없다.

  2) 스태틱 멤버 필드는 this와 전혀 상관이 없다. 그래서 스태틱 멤버 필드는 this를 사용해서 lock을 걸 수 없다. 그렇다면 직접적으로 lock의 대상을 정해주어야 한다. 

  3) 만약 스태틱 멤버 필드가 참조타입이라면 참조 타입 그 자체를 lock의 대상으로 사용하면 되지만 값 타입이라면 골치 아파진다.

  4) 참조타입이면 lock의 대상으로 참조 타입의 참조값 그 자체를 사용하면 된다.

	private int limit = 0;
	public  void SayHello(){
		int hash = Thread.CurrentThread.GetHashCode();
		int count =0;
		lock(this){

 

5. 값타입 스태틱 멤버 필드의 lock

  1) 값타입의 Type 객체를 lock의 대상으로 넣어주면 된다.

  2)  typeof(클래스명) 형식으로 lock을 잡아주면 된다.

	private static int limit = 0;  //값타입의스태틱공유자원limit
	public  void SayHello(){
		int hash = Thread.CurrentThread.GetHashCode();
		int count =0;
		lock(typeof(Top)){  //limit가스태틱공유자원이기때문에lock(this)를사용할수없다.
                            //이는스태틱공유자원의동기화와관련이없다.
                            //typeof(Top)는공기화가보장된다.

 

6. 참조타입 스태틱 멤버 필드의 lock

	private static object obj = new object(); //참조타입의스태틱공유자원obj
	public  void SayHello(){
		int hash = Thread.CurrentThread.GetHashCode();
		int count =0;
		lock(Top.obj){ //공유자원이스태틱참조타입이므로Top.obj과같이사용할수있다.

 

7. 고급 동기화 - Monitor

  1) lock 키워드보다 좀 더 정교한 동기화의 방법을 제공

  2) lock키워드를 사용하면 그 효력은 블록{}으로 감싸있는 내부 전체가 된다. 이에 반해 Monitor클래스를 사용해서 동기화시키면 Monitor.Exit() 함수를 이용해서 동기화의 끝 지점을 지정할 수 있다.

  3) lock키워드를 사용할 때의 동기화 영역은 블록{}으로 표시

  4) Monitor는 Monitor.Enter()함수로 동기화의 시작을 지정할 수 있다.

  5) Monitor.Exit()함수로 동기화가 끝났음을 지정할 수 있다. <-반드시 Enter()로 시작했으면 Exit()로 마쳐야 한다. 안 그러면 데드락 발생함.

  6) Monitor는 동기화의 시작과 끝을 유연하게 조정할 수 있다.

  7) 단순히 lock을 통해 잠금을 설정하고 해제하는 것에 비해서 기능이 많음

  6) Monitor의 멤버는 대부분 static으로 구성되어 있다.

  7) lock에 비해서 좀 더 나은 점은 TryEntry(), Enter(), Exit() 함수와 같이 좀 더 풍부한 함수를 제공하기 때문에 단순히 lock을 통해 잠금을 설정하고 해제하는 것에 비해서 기능이 많다는 점이다.

  6) TryEntry()는 해당 동기화 객체를 잠그다가 실패하면 잠그는 것을 포기하고 나오는 역할을 한다. lock과 달기 결코 Blocking 되지 않는다는 장점!

 

8. 고급 동기화 - Mutex 

  1) 여러 개의 스레드에서 Mutex에 대한 사용을 요청할 때 사용권한을 하나의 스레드에게만 부여하는 방식 

  2) 단계

    - 1단계 : Mutex 객체 생성하기

      > Mutex mtx = new Mutex(false, "mutexsample");

    - 2단계 : Mutex 요청하기

      > 만들어진 뮤텍스를 사용할 권한을 요청한다. 만약 다른 스레드가 mtx를 사용하고 있다면 대기상태에 있으면서 사용권한을 반복적으로 요청하게 된다. 

      > mtx.WaitOne()

    - 3단계 : Mutex 해제하기

      > WaitOne()한 수만큼 ReleaseMutex()를 호출해야 한다.

      > mtx.ReleaseMutex();

 

728x90
반응형