■ CallBack Function (콜백 함수)





1. 존재의 목적
   - 프로그램이 실행되는 동안 지속적으로 수행해야 할 작업이 있을 때.
   - callback 함수를 호출한 쪽의 데이터를 callback 함수가 위치한 곳에서 사용해야 할 때.
  

2. 의미
   - 운영체제가 API함수를 제공하는 것과 달리, 응용프로그램이 callback 함수를 제공한다.
   - 특정 조건을 만족 하였을 때 운영체제가 호출한다.
   - callback 함수는 오직 운영체제가 호출하며, 응용프로그램이 직접 callback 함수를 호출하지 못한다.
   - callback 함수마다 정해진 함수 원형이 있다.

   ※ 조건이 있을 때 윈도우 메시지를 호출 하기 보다 callback 함수를 호출 하는 이유?
      -  윈도우 메시지는(WM_TIMER. 등등) 메시지 마다 우선순위가 있어서 실행 순서에 밀려 늦게 호출 될수 있음.
      -  callback 함수는 조건이 발생 하였을 때 바로 실행됨.


3. 대표적인 callback 함수
    운영체제가 callback 함수를 호출 할 수 있도록 callback 함수를 등록 해주는 함수가 존재한다.
   즉, 응용프로그램은 callback 함수를 윈도우 시스템에 알린다.
    
    - ::SetTimer(hWnd, 2, 5000, NULL);
                VOID CALLBACK TimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime);
                조건 : 지정해준 시간마다 callback 함수 호출

    - ::EnumWindows(WINDENUMPROC lpEnumFunc, LPARAM lParam);
                 BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam);
                 조건 : 최상위 모든 윈도우 검색, 그 핸들을 callback 함수로 전달
                          모든 윈도우를 다 찾거나, callback 함수가 FALSE를 리턴할때까지 호출됨.

    - ::윈도우 등록 및 생성
                 LRESULT CALLBACK WndProc(...)
                 조건 : 메인윈도우가 메시지를 받았을 때


4. callback 함수와 Thread 의 이해
   - callback 함수를 호출할 조건을 만족하는지 지속적으로 검사하는 과정이 필요하다.
     이러한 경우 보통 별도의 Thread 를 이용한다.
   - 즉, Main Thread 와 자식 Thread 는 비동기(Asynchronous) 작업을 수행할 때, 비동기 작업이 완료 되었음을을
     알리기 위한 방법으로 callback 함수(callback 매커니즘) 을 이용한다.




     ※ callback 매커니즘
   

       

<그림 2>는 전형적인 콜백 메커니즘을 보여주고 있다. 콜백 메커니즘의 순서로써
(1) 호출자는 콜백 메서드의 참조(함수 포인터)를 매개 변수로 하여 피호출 메서드를 호출한다
(2) 피호출 메서드는 매개 변수로 전달된 콜백 메서드에 대한 참조를 필드와 같은 곳에 기록해 둔다.
(3) 이제 콜백을 수행할 어떤 조건(이 조건은 다양할 수 있다)이 만족되면 ...
(4) 기록해 둔 콜백 메서드 참조를 이용하여 콜백 메서드를 호출하게 된다.

물론 모든 콜백이 <그림 2>와 같은 순서를 따르는 것은 아니지만 많은 경우 이와 같은 시나리오를 따르는 것이 일반적이다. 콜백을 수행할 조건을 만족하는지 지속적으로 검사하는 과정이 필요하기 때문에 별도의 스레드를 이용하는 경우가 대부분이며, 콜백 메서드를 호출하는 스레드 역시 조건을 검사하는 스레드이기 때문에 콜백 메서드는 서로 다른 스레드에서 호출되는 것이 일반적이다. 이렇게 다중 스레드를 사용하기 때문에 비동기(asynchronous) 작업을 수행할 때 비동기 작업이 완료되었음을 알리기 위한 방법으로 콜백 메커니즘이 많이 사용되곤 한다.

출처 : http://imaso.co.kr/?doc=bbs/gnuboard.php&bo_table=article&wr_id=29268


 

   - callback 함수는 불려지는 쪽에서 부르는 쪽의 데이터를 참조 하거나 핸들링 하는 함수이다.
    다시 말해서 불려지는 쪽에서 부르는 쪽으 DATA를 참조하기 위한 교량 역할을 하는 함수가 callback 함수이다.




cf). callback 함수가 있다는 것을 알고 있었고, thread 가 있다는 것도 알고 간단한 사용법도 알았다.
    그런데 커다란 프로그램 에서는 정말... 복잡하지만 그 존재의 목적 대로 사용하고 있었다.
    이해가 안갔는데...  조금 정리가 되가는 것 같다.
    다음과 같은 경우이다.

1. Main Thread 에서  자료를 읽어 오는데 시간이 너무 오래 걸리는 거야...
   그래!! thread 를 이용하자!!

2. 생성한 Thread 에서 자료를 검색 해야 하는데 자료 검색 함수(메소드) 들이 MainThread 에 있는 거야...
3. 또 검색한 자료 값을 저장해야 하는데 그 변수 또한 Main Thread 에 있어.  Main Thread 와 자식 thread 간에는
   독립된 Stack 메모리를 사용하니까 변수를 고유 할 수 없고,
4. 그렇다고 전역변수를 사용하자니... 전역 변수의 사용은 지양해야해!!
5. Thread 에서 검색과정중 발생한 이벤트 역시 Main Thread 에 넘겨주고 싶어. 발생한 이벤트 마다 
   Main Thread 가 다른 작업을 해주어야 하거든.
6. 그렇다고 Thread 에서 Main Thread 로 ::SendMessage() 함수를 사용 할 수는 없고,
   ::PostSendMessage() 는 안전하지 않으니 조금 사용하기가 그래.

7. callback 함수를 사용하자!!!
   callback 함수는 callback 함수가 불려지는 쪽(Thread)의 데이터를 callback 함수가 있는 곳(Main Thread)에서
   사용할 수가 있거든.




##

Posted by six605
,