파이버는 아래와 같은 단점을 가지고 있습니다....
우선 처리가 적절하게 끝나야 합니다. 적절하게 끝나지 못하고 중간에서 Fiber Context Switching이 된 상태에서 끝나게 된 경우, 해당 Fiber Context에서 돌아가던 변수들이 클리어 되지 않습니다. 이것 때문에 애 먹었습니다. Compuware Error Detection으로 체크하는데 갑자기 Memory Leak과 Resource Leak이 나와 체크하였는데 결과적으로 실행하다가 프로그램 종료와 함께 종료된 Fiber Context에서 선언되고 사용되어진 Class들의 d'tor가 호출되지 않았습니다. 쩝... Thread관련 클래스에는 이상없이 클리어 되던 얘들인데... (상세한 조사는 하지 않고 버그만을 수정하였습니다.)
--> 아마도 Fiber는 커널레벨에서는 Thread에 속하기 때문에 Thread가 종료되기 전에는 Fiber가 끝나도 포함되어 있던 Resource들을 정리하지 않는듯 합니다.
두번째로 User Level Thread인 관계로 OS는 파이버를 쓰레드로 인식하지 않는 관계로 100개의 Fiber가 실행되는 Thread를 1개 가진 Process나 1개의 Fiber가 실행되는 Thread를 1개 가진 Process나 동일 우선 순위를 가집니다. 때로는 Fiber의 부하를 인식하지 못하는 OS는 CPU를 Idle 상태로 만들지도 모릅니다. 결국, OS에게는 몇개의 Fiber가 존재하던 쓰레드 숫자만이 관심있을 뿐입니다.
세번쨰로 인터넷 찾아보면 Single Thread + Fiber 조합으로 쓰시는 분들 있으시다던데, 이는 굉장히 좋지 않은 방법인 듯 보입니다. OS가 CPU당 Thread를 할당하는데 Single Thread일 경우 아마도 멀티 CPU에서 한개의 Thread만을 사용하는 결과를 초래할 듯 보입니다. 물론 이럴경우 다른 CPU에 다른 Process의 Thread가 할당되겠죠. 개인용 PC도 듀얼, 쿼드인 세상에 Single Thread는 아마도 서버에서는 굉장히 좋지 않은 방법인듯 보입니다. 물론 멀티프로세스로 돌리신다면 문제없겠지만... 이경우에는 멀티 프로세스가 CPU당 할당되는 효과를 노리겠죠... 아마도...
네번쨰로 개인적으로 생각하기에 Fiber는 시분할이 아닌 관계로 Fiber당 동일 시간을 할당 받는 것을 보장하지 못하는 관계로 반응성이 Fiber마다 틀립니다.
파이버에 대한 Know-How
공유변수 처리
두 개이상의 Fiber에서 같은 변수를 사용하는 것은 마치 싱글쓰레드 프로그램에서 전역 변수를 여러 함수 내에서 사용하는 것과 비슷합니다. 틀린점이 있다면 파이버같은 경우 Context Switching이 일어나서 같은 변수를 사용한다는 것을 의외로 파악하기 힘들 떄가 있다는 것 정도입니다.
클래스 멤버변수를 같이 사용하는 경우에, 쓰레드와 같은 경우는 성능 저하를 최소화 시키도록 락을 잡는 테크닉이 중요하지만, Fiber 같은 경우는 한 쪽 Fiber에서 멤버 변수를 사용한 것이 Fiber Context Switching 후에 다른 Fiber에 어떤 영향을 주는지 파악하는 것이 중요한 듯 보입니다.
파이버에 대한 주의사항
끝났을 경우 반드시 DeleteFiber로 내용을 정리하여 주어야 합니다. 진정으로 까다로운 부분이 DeleteFiber부분인데 이 함수를 같은 Fiber Context내에서 호출하면 ExitThread가 자동으로 호출되면 해당 파이버를 실행하는 쓰레드가 멈처버립니다. 결국, 다른 Fiber Context내에서 호출해야 합니다.
그럼, 파이버를 왜 쓰는가?
Thread 사용에 대한 Context Switching Overhead나 Locking Overhead를 피하기 위하여 사용합니다. 문서를 찾아보면 어셈블리로 유저레벨에서 쉽게 구현할 수 있을 정도로 구현은 간단하다고 합니다. Fiber를 아주 잘 사용하는 곳이 SQL Server랍니다. 뭐, 특정 태스크에 대하여 Fiber에서 실행하는 옵션이 있는데 CPU사용률이 100%에 육박할 때 사용하면 와따랍니다.
또,Fiber가 좋은 점은 디버깅할 때 편합니다. 뭐... 컨텍스트 스위칭 할 때마다 위치가 변하는 것 말고는 싱글쓰레드 디버깅하는 것과 별반 차이없습니다. 멀티쓰레드와 같이 쓰레드 순서에 따라 불규칙적으로 에러가 난다든지, 싱크문제로 멀쩡하게 에러가 잘 나다가 디버깅만 하면 에러가 안난다든지 하는 문제 없습니다.
자자.. 그럼, MSDN의 공식입장은?
In general, fibers do not provide advantages over a well-designed multi threaded application. However, using fibers can make it easier to port applications that were designed to schedule their own threads.
보다시피, 잘만들어진 멀티쓰레드 어플리케이션의 이점을 주지는 못하지만 쉽게 그들 자신의 쓰레드를 스케줄 하도록 만들어진 프로그램의 포팅을 쉽게 한답니다... 윈도우 버전 3.1용 프로그램 포팅을 염두해둔 듯 합니다.
'윈도우 프로그래밍' 카테고리의 다른 글
64bit 윈도우 프로그래밍 (0) | 2009.08.21 |
---|---|
Low Fragementation Heap(LFH) (0) | 2009.07.03 |
Win32 ThreadPool (0) | 2009.07.03 |
OLE DB의 클래스 역활 (0) | 2009.06.14 |
UDP, recvfrom()에서 WSAECONNRESET(10054) 에러 날 때... (0) | 2009.04.30 |
SetEvent(..) & 멀티쓰레드 버그 (0) | 2009.04.28 |
Win32 과연 어떤 Timer함수를 사용할 것인가? (0) | 2009.04.24 |
First Chance Exception (0) | 2009.04.24 |