정리

[MFC] MFC에서 Thread를 사용할 때는 _beginthread 말고 AfxBeginThread를 사용해야 한다.

저장소/VC++

[출처] [펌글] MFC 에서 쓰레드 관련한 글 |작성자 구리구리


MFC 프로그래밍에서 거의 100% 들어맞는 원칙이 하나 있습니다.
비슷한 기능을 하는 함수가 C/C++ 런타임 라이브러리 API 버전이 있고 앞에 Afx가 붙은 MFC 버전이 있다면 무조건 Afx가 붙은 버전을 써야 한다는 겁니다.
예를 들어, LoadLibrary 같은 것도 MFC에선 AfxLoadLibrary를 써야 합니다.


이런 얘기를 꺼내는 건 다름이 아니라
많은 분들이 MFC에서 _beginthread나 CreateThread를 이용해서 스레드를 만든 다음
그 스레드에서 CWinApp, CView 등의 인스턴스에 액세스하면서 에러를 경험하시는 것 같아서 입니다.


(1) MFC 오브젝트는 '스레드 안전'하지 않습니다.
동일한 오브젝트를 두 스레드에서 동시에 사용하려고 하면 맛 갈 수 있습니다


(2) MFC CWinThread나 AfxBeginThread를 이용하지 않고, _beginthread나 CreateThread로 만든 스레드에서
MFC 오브젝트에 액세스하면 맛 갈 수 있습니다.


(3) MFC 스레드(보조 스레드)에서 다른 스레드로 생성된 CWnd 계열 오브젝트를 사용하면 생각대로 결과가 안 나올 수 있습니다.


MFC 오브젝트는 실제 HWND 같은 핸들을 감싸는 C++ 랩퍼 오브젝트인데, 각각의 랩퍼 오브젝트에 대응되는 실제 HWND 핸들이 무엇인지 알려주는 정보가 스레드마다 개별적으로 사용되는 스레드 로컬 스토리지에 저장되기 때문입니다.
즉 같은 CWnd 오브젝트(같은 메모리 주소)에 액세스하더라도 그 오브젝트가 사용하는 핸들(HWND)가 다를 수 있다는 겁니다.


그러니 보조 스레드에서 뭔가 UI와 관련된 조작을 할 때 직접 하려고 하지 말고
마치 2개의 프로세스가 통신하는 것처럼 ::PostMessage 같은 방법을 이용하는 것이 좋습니다.


또한, 예를 들어, 다른 스레드로 CWnd 오브젝트를 넘길 때 오브젝트를 직접 넘기지 말고 HWND로 넘긴 다음 받은 스레드에서 FromHandle 메소드를 써서 다시 CWnd를 사용하는 식으로 해야 합니다.


이상의 내용은, 왠만한 Visual C++ 프로그래밍 책에는 다 나올 겁니다.


http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/_core_multithreading_with_c.2b2b_.and_mfc.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/_core_Multithreading.3a_.Programming_Tips.asp


이 두 개의 글을 대충 정리한 것입니다.


출처 : 데브피아 vc++ 팁 강좌란 노영선(roh0sun)님 글입니다~~