일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 쉐어포인트코리아
- windows mobile 6.5
- winmodev
- 신동혁
- 안드로이드
- 황광진
- 마이크로소프트
- 헤이맨
- 실버라이트 코리아
- 옴니아2
- 데브피아
- 윈도우폰
- 윈도우모바일
- 윈모데브
- 김춘배
- 거제도
- 루나네스
- 주신영
- 훈스닷넷
- 윈도우폰7
- 소년포비
- 윈도데브
- 스마트폰
- 소년포비소프트
- 신석현
- UX베이커리
- 서진호
- 지승욱
- 윈도우 모바일
- MIX10
- Today
- Total
소년포비의 세계정복!!
[Thread][동기화] Event 본문
WaitHandle 추상 클래스로부터 상속받는 Event 관련 클래스들을 살펴 보자
* Event
지금까지는 동시에 실행되는 여러 Thread 의 공유리소스(Critical Section) 접근에 대한 동기화 관련
클래스들을 살펴 보았다.
이번 글에서는 Thread 들의 활동을 동기화 하는 방법에 대해서 알아 보자.
멀티 Threading 환경에서 동시에 수행되는 여러 Thread 들 중 특정 Thread 의 (자신의) 작업 상태를
다른 Thread 들에게 알려주어야 할 경우가 있다.
즉, Thread 간의 통신을 통하여 서로의 작업 상태를 알려 주는 메커니즘을 가능케 하는 것이 Event 이다.
만일, 두 개의 Thread 가 있다고 가정하자(Thread1 , Thread2)
Thread1 이 자신의 작업을 완료하면 Thread2 에게 끝났다는 사실을 전달해 줘야 하며 Thread2 는 이때 자신의 작업을 수행하고
다시 Thread1에게 작업 완료를 알려줘야 하는 프로그래밍 환경에서 Event 를 사용하면 된다.
이는, 특정 작업을 처리 하기 위해 여러 Thread 들이 분할하여 수행하여야 해야 하는 경우에 유용하게 사용할 수 있다.
이 Event 는 아래의 두 가지 상태를 가진다
- Signaled(신호상태) / Nonsignaled(비 신호상태)
===============================================================================================================================
짐짓 헤갈릴 수 있는 부분을 명시하겠다.
기본적으로 윈도우의 리소스와 관련되는 커널 오브젝트는 Signaled 와 Nonsignaled 상태를 가진다.
만일 특정 프로세스의 커널 오브젝트 일 경우 상태는 다음과 같다.
Sinnaled : 해당 프로세스가 종료된 상태
Non-Signaled : 해당 프로세스가 실행 중인 상태
즉 프로세스가 첨 생성되면 커널 오브젝트가 생성되며 이 때 상태는 Non-Signaled 상태이다가 종료 시 Singaled 상태가 되는 것이다.
따라서 쓰레드에서의 Event 역시
Signaled(신호상태) -> 해당 쓰레드가 실행을 중지한 상태
Non-Signaled(비 신호상태) -> 해당 쓰레드가 실행 중인 상태
가 된다.
(단 프로세스에서는 한반 Signaled 가 되면 다시 Non-Signaled 상태로 변경할 수 없다)
=====================================================================================
Event 는 AutoReset , ManualReset 두 종류가 있다.
닷넷에서는 이 들 이벤트를 위해 AutoResetEvent , ManualResetEvent 클래스를 제공한다.
이 두 클래스는 모두 Win32 Event object 를 나타낸다.
이벤트의 (신호) 상태는 다음과 같이 설정한다.
- Event.Set (상태를 Signaled로 변경) -> 쓰레드의 상태를 중지 상태로 만든다
- Evnet.Reset (상태를 Nonsignaled로 변경) -> 쓰레드의 상태를 실행상태로 만든다
또한 Event 가 신호(Signaled) 상태가 될 때까지 대기하기 위해 WaitXXX (WaitOne,WaitAny,WaitAll) 메소드를 사용할 수 있다
AutoResetEvent 와 ManualResetEvent 이 두 클래스의 차이점은 클래스 이름에서도 유추 되듯이
Reset (비신호 상태)로의 변경이 자동(묵시적)으로 되느냐 그렇지 않느냐는 차이점이 있다.
즉 AutoResetEvent 는 WaitXXX 메서드를 통해 신호(Signaled) 를 받으면 자동으로 비신호(Nonsignaled) 상태가 되지만
ManualResetEvent 는 명시적으로 Reset 메서드를 호출해야지만
비신호상태(Nonsignaled) 상태가 된다.
* Demo
MS 교재에 나오는 예제로 Event 의 흐름을 알아보자
두 Thread (PingThread,PongThread) 가 있다.
이 Thread 는 마치 탁구를 하듯이 ‘핑’,;퐁’ 을 번갈아 가면서 수행하도록 해야 한다.
이를 위해 Event 를 사용하여 두 Thread 간 통신을 통하여 구현한다.
class Class1 { private static AutoResetEvent pingEvent = new AutoResetEvent(false); private static AutoResetEvent pongEvent = new AutoResetEvent(false);
[STAThread] static void { Thread pingThread = new Thread(new ThreadStart(Ping)); Thread pongThread = new Thread(new ThreadStart(Pong)); pingThread.Start(); pongThread.Start(); } static void { for(int i=0;i<10;++i) { //PingThread 는 자신의 일을 수행한다 Console.WriteLine("Ping(핑)"); //PingThread 의 작업이 끝났으므로 //PingEvent 를 신호상태(Signaled)로 변경한다(중지 상태로 변경) //PingEvent 가 신호상태가 되면 WaitOne 로 대기중이던 //PongThread 가 수행될 것이다 pingEvent.Set();
//PongEvent 에게 신호를 받도록 한다 //즉 PongEvent 가 중지상태(Signaled)가 될때 까지 기다린다 pongEvent.WaitOne(); } } static void Pong() { for(int i=0;i<10;++i) { //PingEvent 가 신호상태가 될때까지 대기한다. pingEvent.WaitOne();
//PongThread 는 자신의 일을 수행한다 Console.WriteLine("Pong(퐁)");
//PongThread 의 작업이 끝났으므로 //PongEvent 를 신호상태(Signaled)로 변경한다.(중지 상태로 변경) //역시 WaitOne 로 대기중이던 PingThread 가 수행될 것이다. pongEvent.Set(); } } } |
- 결과
두 Thread 가 Event로 통신하면서 작업을 한번씩 번갈아 가면서 수행하는 것을 알 수 있다.
만일 Evnet 를 이용하지 않고 단순히 두 Thread 를 동시에 실행하면 당연하겠지만 아래와 유사하게 수행될 것이다.
'프로그램 세상 > C#' 카테고리의 다른 글
[ExecuteUnit] Process & Thread 개요 (0) | 2009.10.06 |
---|---|
[ExecuteUnit] Process 다루기 Demo (0) | 2009.10.06 |
[Thread] Thread 메서드에 매개변수 넘기기 (0) | 2009.10.06 |
WMI를 활용한 원격(로컬)컴퓨터 CPU사용량 실시간 모니터링 (0) | 2009.10.06 |
윈폼or모듈단위에서 특정 웹페이지 호출하기 (0) | 2009.10.06 |