http://blog.naver.com/zacronan?Redirect=Log&logNo=40018174412
http://airtight.yonsei.ac.kr/research/COM/thread_apartment.htm

1-2 스레딩 모델

먼저 이 부분을 설명하기 위해서는 아파트먼트(Apartment)라는 것에 대해 설명이 필요하다. 아파트먼트는 하나의 프로세스 내에서 여러 개의 스레드를 가지고 각각의 스레드 동기화 문제를 해결하기 위해 나온 것으로 각 오브젝트를 가지고 있는 하나의 방이라는 개념으로 이해하면 된다. 각 아파트먼트당 하나의 스레드가 존재하며 오브젝트는 적당한 아파트먼트 안으로 들어가게 된다.

이러한 스레딩 모델(Threading Model)은 레지스트리에서 CLSID의 스레딩 모델의 값을 보면 된다. 가능한 경우는 스레딩 모델이 아예 없거나 아파트먼트, 프리(Free), 보스(Both)가 되는 것이다. 아파트먼트는 STA 모델을 가리키며 프리는 MTA 모델을, 보스는 STA, MTA 둘 다 지원한다는 것을 말한다. 이 값이 아예 없다는 것은 main STA에서 동작한다는 것을 말하고 이 main STA는 프로세스가 초기에 주 스레드에서 호출한 CoInitializeEx 값에 의해 결정된다.




① STA(Single Threaded Apartment)

STA 내에서 서버는 각각의 아파트먼트 내에 각 오브젝트가 존재하며 하나의 프로세스 내에서 각 아파트먼트 내에 각 오브젝트가 들어가 있게 된다. 이 경우는 CoInitializeEx(NULL,COINIT_APARTMENTTHREADED)를 각각의 스레드당 호출하여 초기화 된다. 이러한 각각의 오브젝트 호출은 메시지에 의해 동기화 된다. 즉 이러한 메시지를 통해 동기화 된다는 것은 메시지 루프를 가져야 한다는 얘기이다.

하나의 아파트먼트 내에서는 프록시의 개입 없이 직접적으로 호출할 수 있으나 다른 아파트먼트 내에서는 이렇게 될 수는 없다. 즉 하나의 메소드 호출은 클래스 네임이 OleMainThreadWndClass를 가지는 윈도우 클래스가 등록한 WndProc로 가서 적당한 Interface의 메소드를 호출하게 된다. 이러한 모델 내에서의 호출은 그림 5와 같다.










그림 5 : STA에서의 메시지 큐


그림 5에서 보는 것처럼 서버로의 모든 호출은 큐(Queue) 속에서 들어가며 GetMessage,DispatchMessage에 의해 해당 오브젝트로 전달된다.




② .MTA(Multi Threaded Apartment)

MTA 내에서 하나의 아파트먼트 내에 여러 개의 스레드와 오브젝트가 들어가게 되며 따라서 오직 한 번만 CoInitializeEx(NULL, COINIT_MULTITHREADED)를 호출하면 된다. 이 경우에는 여러 개의 스레드가 동시에 오브젝트의 메소드로 접근할 수 있기 때문에 Reentrant하도록 소스가 작성되거나 동기화 문제를 코드 안에서 해결해야 한다. 하지만 서버 안에서의 스레드간 인터페이스 전달에 프록시가 개입할 필요가 없다.

또한 STA로 작성하는 것보다 빠른 속도를 보이는 멀티 스레드의 장점을 충분히 활용할 수

가 있으며 하나의 프로세스 내에 오직 하나의 MTA만 만들어질 수 있다.




③ 혼합 모델

이 모델은 프로세스가 한 개의 MTA와 한 개 이상의 STA를 가진다는 것을 의미한다.




④ STA와 MTA와 혼합 모델에서의 선택

어떤 오브젝트의 모델을 선택하는 것은 각기 장단점이 존재하기 때문에 상황에 맞게 선택해야 하는데, STA에서는 프로그래머가 스레드간의 동기화를 신경쓸 필요가 없다. 그러나 여기서 다른 아파트먼트로 인터페이스를 전달하기 위해서는 프록시의 개입을 필요로 하므로 느려질 수 있으며, 또한 객체로의 메소드 호출이 메시지 루프(Loop)를 통해 한번에 하나씩 만 처리되기 때문에 멀티 스레드의 장점을 충분히 활용할 수가 없게 된다.

그러나 MTA를 선택한 경우 서버 객체의 구현자는 여러 개의 스레드가 동시에 메소드 호출을 수행할 수가 있으므로 코드는 Reentrant하게 작성되거나 Mutex, Critical Section, Event를 통해 동기화 코드를 작성해야 한다. 따라서 작성이 어려워지게 되지만 이 경우라고 해도 수많은 사용자가 사용할 수 있는 오브젝트라면 한번 고려해볼 만하다.

+ Recent posts