티스토리 뷰

'fiber' testing code

이번에 작업을 담당하게 된 엔진에는 특이한 기능을 쓰고 있는데, 바로 'fiber'이다.

MSDN을 보면, 'UNIX 기반 서버 시스템의 포팅을 돕기 위해서 만들었다'라고 언급되어 있다.


즉..!!!.. 처음부터 제작하는 어플리케이션용이 아니란 뜻인데... 이 엔진을 처음 만드신 분이
UNIX 포팅을 꽤 하셨나 보다..-_-..

(뭐.. 뒷담이라고 하기엔 뭣 하지만... 전형적인 C 스타일의 설계를 C++로 커버하기 위해서
  여러가지 테크닉 아닌 테크닉들을 쓰고 있는데 그 대표적인 형태이다.
  물론, 데이터 처리등에 있어서 C++ 스럽지 않은 C++의 사용은 논외로 하자.
)


어찌되었건.. 지금은 엔진의 가장 큰 부분을 내가 쓰레드로 옮겨서 테스팅 중이지만, fiber를 이용해서
구성되어 있는 이상 어떤 것인지 알아둘 필요는 있다.


fiber는 근본적으로 thread와 동일하다. 스케쥴링에 대한 것만 제외하고 말이다.
thread가 윈도우 스케쥴러에 따라사 스케쥴링 되는 것과 달리 fiber는 수동으로 스케쥴 된다. 아니 한다.

A 쓰레드에서 B쓰레드로 넘어가기 위해서 명시적인 SwitchToFiber를 콜 해야 안다.

콜하게 되면, A쓰레드는 Sleep상태로 들어가게 되고, 스케쥴러는 B 쓰레드를 스케쥴링한다.
반대로 B에서 A로 넘어가기 위해서도 API 호출이 필요한 것이다.

쓰레드와의 가장 큰 차이점인 스케쥴링이 수동으로 가능해짐에 따라 Synchornize를 위한 객체들이
필요하지 않게 된다.

메뉴얼하게 스케쥴링하기 때문에 데이터가 동기화 되는 시점을 조절할 수 있다.
(게다가 실제로 시리얼하게 처리되기 때문에... 절대 쓰레드간의 데이터 Corruption이 발생하지 않는다)


웹에서 찾은 예제를 살짝 살펴보자..


-- Test code from --
http://nienie.com/~masapico/api_SwitchToFiber.html


#define _WIN32_WINNT 0x0500

#include <Windows.h>


LPVOID pFiber[3];
LPVOID pMainFiber;

VOID WINAPI DoFiber(DWORD FiberCount)
{
   printf("Thread %d: startup \n", FiberCount);
   Sleep(1000);
   printf("Thread %d: Ends \n", FiberCount);

   if(FiberCount<2)
    SwitchToFiber(pFiber[FiberCount+1]);
   else
    SwitchToFiber(pMainFiber);
}


DWORD WINAPI DoMainFiber(void *p)
{
   pMainFiber = ConvertThreadToFiber(NULL);

   printf("Main Startup\n");
   ::SwitchToFiber(pFiber[0]);

   printf("Main Ends\n");
   return(0);
}


int main(int argc, char **argv)
{
   HANDLE hThread;
   int i;

   for(i=0; i<3; i++) {
    pFiber[i] = CreateFiber(0, (LPFIBER_START_ROUTINE)DoFiber, (LPVOID)i);
   }
   hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)DoMainFiber, NULL, 0, NULL);

   WaitForSingleObject(hThread, INFINITE);

   CloseHandle(hThread);

   return(0);
}


---------------- 수행 결과 -------
Main Startup
Thread 0: startup
Thread 0: Ends
Thread 1: startup
Thread 1: Ends
Thread 2: startup
Thread 2: Ends
Main Ends


결과를 보면, 정확하게 프로그램 코드대로(?) 동작한 것을 알 수 있다.
만약 fiber가 아닌 순수하게 쓰레드로 작성했다면, 반복 수행했을때 결과가 달라지는 케이스도 발생하겠지만
이 API를 사용한 경우는 정말 의도대로 동작하는 것을 알 수 있다.


결론적으로 말하자면, 쓰레드를 사용하기는 하지만, 병렬적으로 처리되지 않기 때문에 생각할 수 있는 장점은
Data의 동기화 문제가 발생하지 않는다

하지만, 병렬적인 처리가 되지 않기 때문에 제기되는 문제점은
병렬처리의 장점을 전혀 기대할 수 없다


뭐.. 누군가 이 API로 프로그램을 작성한다면 말리고 싶은 마음은 없다.
하지만, 과연 어떤 목적으로 이걸 써서 만들려고 하는지 진지하게 고민해보자.

멋지게 만드는 것도 좋지만, Co-Work을 해야 한다면 다른 사람들에게 친숙한 패턴으로 작성해 주는게
백만배는 생산적이지 않을까?

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
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
글 보관함