프로그래밍(Programming)/C#

c# AutoResetEvent, ManualResetEvent (커널모드)

3DMP 2022. 11. 27. 21:36

lock 클래스는 임의로 만든 lock 클래스이고 실제 중요한것은 AutoResetEvent 이다

 

초기 AutoResetEvent 값은 true 였고, 초기 값을 false 로 설정 하는것도 가능하다

 

waitOne() 함수를 만나 상태가 false 가 되면서 락을 소유하게 된다, 그래서 다른 스레드는 더이상 접근하게 못하게 되다가

 

.Set() 을 하는 순간 AutoResetEvent  가 다시 true 상태가 됨으로 이후 부턴 다른 스레드도

waitOne 에서 락을 획득하여 들어올 수 있게 된다

 

 

AutoResetEvent 는 waitOne 에 진입함과 동시에 자신의 상태를 false 로 만든다는 특징이 있다

 

 

 

 

이렇게 코드를 돌릴때 한쪽에서만 공유변수 _num 을 증가 또는 감소 할 수 있게 된다

 

 

 

 

 

ManualResetEvent

이건 문을 자동으로 닫진 않는다 즉 waitOne 에서 lock 을 획득하면 자도으로 ManualResetEvent 상태를 false 로 만들지 않는다는 것이고 이것을 수기로 해줘야 한다

 

ManualResetEvent.Reset();  false 로 바꾸는 함수

 

 

 

이렇게 하면 문제가 발생하는데

reset 과 watiOne 사이에 여러 스레드가 동시에 들어올 수 있기 때문에 정확한 처리가 되지 않는다

 

하지만 의도가 여러 스레드의 입장이 동시에 가능하게 할 것이라면 이 처리는 맞게 된다

 

 

 

ex ManualResetEvet 를 댐 같은것이라 생각하면 예시가 될 수 있는데

 

사용자가 게임 진입 버튼을 누르기 전까지 ManualResetEvet  에 의해 모든 스레드가 대기 하고 있다가

 

버튼 을 누르면 인터넷으로부터 데이터를 받아오거나 로컬 파일을 동시에 읽는다던가 맵을 이동하는 등

여러 스레드들을 버튼 누른 시점 이후부터 동작하게 하기위한 스레드 대기의 용도로 사용 할 수 도 있다

 

 

spinlock 은 유저모드에서 실행되는거라 cpu 타임만 갉아 먹는데

AutoResetEvent, ManualResetEvent 은 커널모드에서 돌아가는 것이기 때문에 context switch 가 일어나게 되어 성능이 유저모드에 비해 떨어 질 수가 있다

 

 

 

 

 

 

커널모드 동기화 중에 다른 것이 Mutex 가 있다

위의  WiatOne(문을 잠금) 으로 lock 을 소유하고 ReleaseMutex(문을 다시 연다) 를 통해서 mutex 의 lock 을 놓아준다

 

 

 

mutex 와 autoResetEvent 의 차이는

 

Mutex 는 lock을  잡을떄 카운팅을 할 수 있고 mutex 는 스레드 id 또한 갖고 있어서 

문제가 있을때 유용한데 추가 비용이 좀 더 들어간다

 

 

 

 

반응형