1. 크기(size) 및 효율성(performance)의 이유로 MFC 객체(Object)는 스레드에 안전한 구조가 아니다.


2. MFC 객체에 접근(Access)하기 위해서는 CWinThread 객체를 사용한 스레드여야 한다. (User-Interface Thread, Worker Thread)

  • User-Interface Thread와 Worker Thread의 차이
    User-Interface Thread는 스레드 자체의 메시지 큐를 가지며 일반적으로 UI를 포함한다.


3. 일반적인 규칙으로 MFC 객체는 그것을 생성한 스레드에서만 접근할 수 있다. MFC는 윈도우 핸들과 윈도우 객체를 연결하는 맵(Windows Handle Maps)을 가지는데 이것은 스레드의 로컬 영역에 저장되기 때문이다.

  • Worker Thread에서 CDocument의 UpdateAllViews 나 CView의 UpdateWindow 등을 호출해도 뷰는 업데이트 되지 않는다.
  • Worker Thread에서 AfxGetMainWnd 등을 호출하면 NULL이 반환된다.
  • Worker Thread에서 CDialog의 UpdateData 등을 호출하면 ASSERT 에러가 난다.
  • Worker Thread에서 UI를 직접 접근할 경우 Dead lock에 빠질 수 있다.


4. SendMessage와 PostMessage의 차이를 알자.

  • SendMessage를 호출하면 윈도우의 메시지 프로시저를 바로 호출해서 결과를 리턴 받는다.
  • PostMessage를 호출하면 메시지가 시스템 메시지 큐에 보내지고 호출한 함수는 바로 리턴이 된다. 시스템은 해당 윈도우 스레드의 메시지 큐에 메시지를 보내고 메시지가 처리된다.
  • 따라서 Worker Thread에서 SendMessage를 호출하면 Worker Thread에서 메시지 핸들러를 호출하게 되는것이고, PostMessage를 호출하면 메인 Thread에서 메시지 핸들러를 호출하게 되는것이다.



MFC 어플리케이션에서 Worker Thread를 사용할 경우 지켜야 할 규칙

  1. UI에 대한 접근은 UI를 생성한 클래스에서만 한다. (Worker Thread에서 UI 접근 함수를 직접 호출하지 않는다.)
  2. 메인 스레드와 서브 스레드(Worker Thread)에서 동시에 접근하는 Data는 최대한 줄인다.
  3. 서브 스레드(Worker Thread)에서 처리한 작업은 사용자 메시지를 만든 후 PostMessage로 보내서 메인 스레드에서 처리할 수 있도록 한다.



References