안녕하세요~ "쓰레드 풀 함써보자!!" 도전중인 jerry 입니다!! ^^

 

오늘은 쓰레드 풀에 관한 두번째 이야기로

첫번째 글에서 언급했던 쓰레드 1000마리용 쓰레드 풀 만들기에 도전해 보도록 하겠습니다.~

 

여기서 잠깐

 

쓰레드 풀과 쓰레드에 대해서 잠시 집고 넘어가 보겠습니다.

 

혹시, 이 글을 읽고 계신 분중에

 

"그냥 쓰레드를 필요한데로 만들어 쓰면 되지"

"왜 힘들게 쓰레드 풀을 만들 필요가 있나"

 

이런 의문이 생기지 않으신가요?

 

왜 굳이 쓰레드 풀이 필요한걸까요??

 

"그냥 쓰레드 1000마리가 필요하면 그냥 쓰레드 1000마리 Create 하면되지..

풀은 왠말인가??? 뭐하러 만들어??~~ 귀찮아ㅋㅋ"

 

요런 생각이 드실지 모르지만...

 

막상 직접 1000마리의 쓰레드를 만드시려면.. 머리에 쮜가 날것입니다.

 

일딴, 쓰레드를 사용하기 위해서는 우선 ThreadStart 라는 델리게이트를 이용해야 하는데

이 델리게이트는 인수값이 없는 메쏘드만 모시기 때문에

쓰레드에 값을 직접 전달하는데도 상당한 어려움이 있죠.

 

그리고.. 직접 쓰레드를 호출하지 않는 가장 큰 이유는 1000마리 만들면..

1000마리 모두 제멋대로 놀다보니.. 손오공에 분실술처럼 완젼 통제불능상태가 됩니다..

 

그래서.. 그냥 맘편하게 쓰레드를 모아다가 풀에 넣어 놓으시면

자기들이 알아서 CPU 부하도 생각해가면서 잘 합니다...

 

많은 쓰레드를 생성할때 쓰레드 풀은 필수라는거~~ 기억하시고!

 

자~~

 

그럼 이제 앞에 쏘쓰를 활용해서~

1000마리의 쓰레드를 만들어 보겠습니다.

 

 2-1.PNG

 

MSDN 에 예제소스에 FibonacciCalculations 값을 1000으로 바꿨었죠?

자.. 요렇게 그냥 실행시키면... WaitHandle.WaitAll 에서 64개 이상 안되요!!! 하고 오류가 납니다...

음.. 함수자체를 넘 약~하게 만들었나... 최대값이 64개라나...

당장 이 함수를 버립니다...

 

ㅎㅎ 쿨하게 버린다고 끝난건 아니고..

이제 직접 만들어 줘야 하는데...

 

WaitHandle.WaitAll 에 역활이 뭐였는지 알아 봅시당~

MSDN 참조 : http://msdn.microsoft.com/ko-kr/library/z6w25xa6.aspx

 

보시면 사실 뭐 별거 없습니다.

그냥 "지정된 배열의 모든 요소가 신호를 받기를 기다립니다."

딱 요기능만 하는데 좀 더 풀이해서 말하면...

 

쓰레드를 닌자에 메타포 시켜봅시다~~

 

닌자1호(쓰레드), 닌자2호(쓰레드), 닌자3호(쓰레드)... 이런 애들이 만들어 질때마다

단검를 하나씩 손에 줘준다고 생각해 봅시다..

그리고 요렇게 명령하는거죠.. "닌자1,2,3호~ 너의 임무가 완수되면, 단검을 써서 자결하라."

흐미... 돌아올수 없는 임무를 주는 거죠...

 

돌아오면 안되요... 원래 컴퓨터에 세계란게 그렇잖아요..

필요없으면 바로바로 없애 줘야 합니다.... (앗... 잔인함...)

 

위 소스에서 단검 역활을 하는 애가 ManualResetEvent 입니다.

 

Fibonacci 수만큼 만들어서

쓰레드풀에 들어가기 전에 하나씩 손에 쥐어주는 부분입니다...

 

doneEvents[i] = new ManualRestEvent(false);  <= 단검!!!

Fibonacci f = new Fibonacci(r.Next(20,40), doneEvents[i]);  <= 손에 쥐어줍니다.

 

자 그리고 쓰레드 풀로 뛰어 들어갑니다... 창~창~창 적들과 한판 붙고!!!! 자결!!!! 으.....

 

ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);

 

그럼이제 ... 자결한 닌자의 단검에 묻은 혈흔을 확인합니다....

 

닌자1호의 단검에 혈흔이 있으면 1호는 임무완수...

모두의 단검에 혈흔이 있는걸 확인할때 까지... 지켜보는 거죠...

 

WaitHandle.WaitAll(doneEvents) <= 단검에 혈흔을 확인합니다.

 

자 근데 앞에서 보았드시...

WaitHandle.WaitAll 이란 애는 단검이 64개 이상이면... 경끼를 일으킵니다. (피를 넘 많이 봤나?)

 

허니.. 우리가 직접 이런 역활을 하는 애를 만들어 봅시다!!!

 

Simple합니다.

 

클래스를 만들어 봅시다!!!

 

1번. bool[] _fs;  <= 부울로 단검배열완성!

 

2번. foreach(bool _b in _fs) <= 단검배열을 하나씩 체크해서 혈흔이 없으면 false!!

        {

           if(!_b)

                return false;

         }

 

끝났습니다.

 

소스 보시죠...

 

  2-2.PNG

 

여기서 _dMethod 가 뭔지 애매하실듯....

 

사실 단검만 만들자니... 객채 분위기가 안나서... 그냥 닌자의 임무도 함께 패키지로 넣었습니다.

그리고 이름을 TPool 이라 명하고... TPool 을 활용해서~ 쓰레드 1000 마리를 만들어 봅시다!!!

쏘쓰완성!!!

 

2-4.PNG

넵~ 직접 만든 TPool 을 써서 여기에 임무를 살짝 겨뜰여서(DMethod)

ThreadPool 로 고고 하시고...

 

Check 함수로... 단검에 흔적을 봅니다...

 

소스 첨부합니다 직접 확인해보세요~~~ ^^

ConsoleApplication3.zip

 

쓰레드 800개 생성을 넘어가고 있는 인증샷!!!

 

2-5.PNG 

 

그런데.. 정말 쓰레드 1000마리가 풀속에서 놀고 있는 걸까요???

사실 이속에는 비밀이 숨겨져 있습니다!!!

 

고건. 담은 편에서 그 숨겨진 비밀을 파해쳐 보도록 하겠습니닷~ 헤헤..

 

 

 





profile

I love C# ~~ ^^