Just For Fun

mekiboss.egloos.com

포토로그



C#에서의 멀티 스레드(Multi Thread) 동기화 by 연쇄번개

수행하고자 했던 작업은 다음과 같다.



1개의 다운로드 스레드와

1개의 타이머 스레드가 동시에 동작을 시작.


다운로드 스레드가 먼저 종료된 경우,

다운로드 된 정보를 반영하고, 두 스레드를 모두 종료.


타이머 스레드가 먼저 종료된 경우,

다운로드 스레드를 종료시키고 자신도 종료.


즉, 두 스레드는 서로 경쟁상태에 있으며, 먼저 끝난 스레드가 다른 스레드를 종료 시킴.



초기에는

두개의 ManualResetEvent를 각각 선언하고


public ManualResetEvent download_complete = new ManualResetEvent(false);

public ManualResetEvent timer_complete = new ManualResetEvent(false);


if 조건문 안에 각각의 Waitone 대기 메서드를 이용하여


if(download_complete.waitone() == true || timer_complete.waintone() == true)


어느 스레드가 먼저 종료되는지 확인하였다.


하지만 Waintone 메서드의 특성 상, 자신이 조건을 통과할 때 까지 다른 스레드를 막는 현상이 발생하여

정상적인 경쟁이 일어나지 않음. 즉 다운로드 이벤트가 끝날때까지 기다렸다가 타이머 이벤트를 확인함.



waintone 메서드로는 문제 해결이 불가능하여, MSDN과 구글을 검색


http://msdn.microsoft.com/ko-kr/library/ms173179%28v=vs.90%29.aspx

http://www.hanb.co.kr/network/view.html?bi_id=360

http://www.hanb.co.kr/network/view.html?bi_id=377

http://msdn.microsoft.com/ko-kr/library/tdykks7z.aspx


요약하자면, WaitHandle 클래스와 WaitAny 메서드를 이용하면, 어느 한 스레드가 종료되는 즉시

그 이후의 명령어로 진행이 가능함. 따라서


WaitHandle[] waitHandles = new WaitHandle[2] ;

public ManualResetEvent download_complete = new ManualResetEvent(false);

public ManualResetEvent timer_complete = new ManualResetEvent(false);


위와같이 waitHandle 클래스를 선언해놓고, 해당 스레드를 실행하기 전에


waitHandles[0] = download_complete;

waitHandles[1] = timer_complete;


로 할당. 이후에 있었던 조건문은


WaitHandle.WaitAny(waitHandles)


메서드로 변경. 두 개의 스레드 중 하나의 스레드라도 종료되서 이벤트 핸들러가 Set 상태가 되면

다음 명령어르 진행된다. 즉 핸들에 대한 소유권을 얻고, 대기 상태를 끝낸다.


ManualResetEvent 핸들러를 사용했기 때문에, 각 스레드의 시작과 종료시에

해당 핸들러는 Reset 하고 Set 해주어야 한다.

이러한 방법으로 다운로드 타이머를 사용 하였다.

덧글

댓글 입력 영역



통계 위젯 (화이트)

00
2
19828