STA와 MTA를 설명해 주시겠습니까?


391

STA와 MTA를 자신의 말로 설명 할 수 있습니까?

또한 아파트 스레드는 무엇이며 COM에만 해당됩니까? 그렇다면 왜 그렇습니까?


1
참조 : 이해 COM 아파트 1 부 , 2 부
JRH

답변:


361

COM 스레딩 모델을 "아파트"모델이라고합니다. 여기서 초기화 된 COM 개체의 실행 컨텍스트는 단일 스레드 (단일 스레드 아파트) 또는 많은 스레드 (멀티 스레드 아파트)와 연결됩니다. 이 모델에서 아파트에서 초기화 된 COM 개체는 런타임 동안 해당 아파트의 일부입니다.

STA 모델은 스레드로부터 안전하지 않은 COM 개체에 사용됩니다. 즉, 자체 동기화를 처리하지 않습니다. 이것의 일반적인 사용은 UI 구성 요소입니다. 따라서 다른 스레드가 오브젝트와 상호 작용해야하는 경우 (예 : 양식의 단추 누름) 메시지는 STA 스레드에 마샬링됩니다. Windows Forms 메시지 펌핑 시스템이 그 예입니다.

COM 개체가 자체 동기화를 처리 할 수 ​​있으면 MTA 모델을 사용하여 여러 스레드가 마샬링 된 호출없이 개체와 상호 작용할 수 있습니다.


1
자세한 내용은 다음을 참조하십시오 : 정보 : OLE 스레딩 모델의 설명 및 작동 .
noseratio

208

그것은 모두 개체 호출이 처리되는 방법과 필요한 보호 수준에 달려 있습니다. COM 개체는 런타임에 여러 스레드가 동시에 호출되는 것을 방지하도록 요청할 수 있습니다. 다른 스레드에서 동시에 호출 할 수없는 스레드는 자체 데이터를 보호해야합니다.

또한 사용자 인터페이스 스레드에서 호출하는 경우 런타임에서 COM 개체 호출이 사용자 인터페이스를 차단하지 못하도록해야합니다.

아파트는 라이브에 객체위한 장소입니다, 그들은 하나 개 이상의 스레드가 포함되어 있습니다. 아파트는 전화를 걸 때 발생하는 일을 정의합니다. 아파트의 객체에 대한 호출은 해당 아파트의 스레드에서 수신되고 처리됩니다. 단, 이미 올바른 아파트에있는 스레드의 호출은 자체적으로 처리됩니다 (즉, 객체에 대한 직접 호출).

스레드는 단일 스레드 아파트 (이 경우 해당 아파트의 유일한 스레드) 또는 다중 스레드 아파트에있을 수 있습니다. 스레드가 해당 스레드에 대해 COM을 초기화 할시기를 지정합니다.

STA은 기본적으로 특정 스레드와 연결된 사용자 인터페이스와의 호환성을위한 것입니다. STA은 숨겨진 윈도우에 대한 윈도우 메시지를 수신함으로써 처리를위한 호출 통지를 수신하고; 아웃 바운드 호출을 수행하면 다른 창 메시지가 처리되지 않도록 모달 메시지 루프를 시작합니다. 애플리케이션이 다른 메시지에 응답 할 수 있도록 호출 할 메시지 필터를 지정할 수 있습니다.

반대로 모든 MTA 스레드는 프로세스에 대해 단일 MTA를 공유합니다. COM은 사용 가능한 스레드가 없으면 풀 제한까지 들어오는 호출을 처리하기 위해 새 작업자 스레드를 시작할 수 있습니다. 아웃 바운드 호출을하는 스레드는 단순히 차단됩니다.

간단하게 ThreadingModel하기 위해 클래스 키 의 값을 설정하여 DLL에서 구현 된 객체 만 레지스트리에서 지원하는 것으로 간주합니다 . 네 가지 옵션이 있습니다.

  • 메인 스레드 ( ThreadingModel값이 없음). 객체는 호스트의 기본 UI 스레드에서 생성되며 모든 호출은 해당 스레드에 마샬링됩니다. 클래스 팩토리는 해당 스레드에서만 호출됩니다.
  • Apartment. 이것은 클래스가 모든 단일 스레드 모드 스레드에서 실행될 수 있음을 나타냅니다. 스레드를 작성하는 스레드가 STA 스레드 인 경우 오브젝트는 해당 스레드에서 실행되고 그렇지 않으면 기본 STA에서 작성됩니다. 기본 STA가 없으면 STA 스레드가 작성됩니다. 이는 아파트 객체를 생성하는 MTA 스레드가 다른 스레드에 대한 모든 호출을 마샬링한다는 것을 의미합니다. 클래스 팩토리는 여러 STA 스레드에 의해 동시에 호출 될 수 있으므로 내부 데이터를 보호해야합니다.
  • Free. 이것은 MTA에서 실행되도록 설계된 클래스를 나타냅니다. STA 스레드에 의해 생성 된 경우에도 항상 MTA에로드되므로 STA 스레드의 호출이 마샬링됩니다. 이는 Free일반적으로 객체가 차단 될 것으로 예상하여 작성 되기 때문 입니다.
  • Both. 이 클래스는 어느 아파트에서든 유연하고로드가 가능합니다. 그러나 두 요구 사항 모두에 맞게 작성해야합니다. MTA에로드 된 경우 동시 호출로부터 내부 상태를 보호해야하지만 STA에로드 된 경우 차단해서는 안됩니다.

.NET Framework에서 기본적으로 [STAThread]UI를 생성하는 모든 스레드에서 사용하십시오. 작업자 스레드는 Apartment표시된 COM 구성 요소 를 사용하지 않는 한 MTA를 사용해야합니다 .이 경우 STA을 사용하여 동일한 구성 요소가 여러 스레드에서 호출되는 경우 마샬링 오버 헤드 및 확장 성 문제를 피할 수 있습니다 (각 스레드는 대기해야 함) 차례로 구성 요소). 구성 요소가 STA에 있든 MTA에 있든 상관없이 스레드 당 별도의 COM 개체를 사용하면 훨씬 쉽게 처리 할 수 ​​있습니다.


마지막 결론이 마음에 들지만 UI에 UserControl을 추가하여 로더와 같은 gif를 재생하는 것뿐이라면 어떻게해야합니까?이 문제가 있습니다. , 같은 스레드에 있으면 GIF가 회전하지 않습니다 ... UI의 MTA가 좋은 아이디어인지 잘 모르겠습니다. 어떻게 하시겠습니까?
Yogurtu

2
@ Yogurtu : 왜 COM 스레딩 모델이 걱정됩니까? STA / MTA 결정은 코드에서 COM 객체를 사용하는 경우에만 관련이 있습니다. UI에는 MTA를 사용할 수 없습니다. .NET의 내부는 그런 식으로 사용되지 않습니다. 애니메이션이 중지되면 UI 스레드에서 메시지 펌핑을 중지했기 때문입니다. 장기 실행 작업을 BackgroundWorker로 이동하거나 작은 단계로 나눕니다. 부드러운 60Hz 애니메이션을 유지하려면 16ms 미만의 작업이 필요합니다!
Mike Dimmick

"아파트"와 appdomain의 차이점은 무엇입니까?
Puchacz 2016 년

78

나는 기존의 설명이 너무 조잡하다는 것을 알았습니다. 다음은 평범한 영어로 된 설명입니다.

STA : 스레드가 STA으로 설정된 COM 개체를 생성하면 (CoCreateXXX를 호출 할 때 COM 개체를 STA 모드로 설정하는 플래그를 전달할 수 있음)이 스레드 만이 COM 개체에 액세스 할 수 있습니다 (STA의 의미-단일 스레드 아파트) ),이 COM 객체에서 메소드를 호출하려고하는 다른 스레드는 후드 아래에서 COM 객체를 생성 (소유)하는 스레드에 메시지를 자동으로 전달합니다. 이것은 UI 컨트롤을 만든 스레드 만 직접 액세스 할 수 있다는 사실과 매우 유사합니다. 이 메커니즘은 복잡한 잠금 / 잠금 해제 작업을 방지하기위한 것입니다.

MTA : 스레드가 MTA로 설정된 COM 개체를 만들면 거의 모든 스레드가 직접 메서드를 호출 할 수 있습니다.

그것은 그것의 요지입니다. 기술적으로 'STA'단락과 같이 언급하지 않은 세부 정보가 있지만 작성자 스레드 자체는 STA이어야합니다. 그러나 이것은 STA / MTA / NA를 이해하기 위해 알아야 할 모든 것입니다.


23

STA (Single Threaded Apartment)는 기본적으로 한 번에 하나의 스레드 만 코드와 상호 작용한다는 개념입니다. 아파트 통화는 창 메시지 (보이지 않는 창 사용)를 통해 마샬링됩니다. 이를 통해 통화가 대기되고 작업이 완료 될 때까지 기다릴 수 있습니다.

MTA (Multi Threaded Apartment)는 많은 스레드가 동시에 작동 할 수있는 곳이며 스레드 보안을 처리하는 개발자는 귀하의 책임입니다.

COM에는 스레딩 모델에 대해 더 많은 정보가 있지만 모델이 무엇인지 이해하는 데 어려움이 있다면 STA이 무엇인지, 어떻게 작동하는지 이해하는 것이 대부분의 COM 개체가 STA이기 때문에 가장 좋은 출발점이 될 것입니다.

아파트 스레드, 스레드가 사용중인 객체와 동일한 아파트에있는 경우 아파트 스레드입니다. 나는 이것이 상호 작용하는 객체와 스레드에 대해서만 이야기하는 방법이기 때문에 이것은 단지 COM 개념이라고 생각합니다 ...


19

COM 또는 OLE 컨트롤을 호스팅하는 각 EXE는 아파트 상태를 정의합니다. 아파트 상태는 기본적으로 STA입니다 (대부분의 프로그램은 STA이어야 함).

STA- 필요에 따라 모든 OLE 제어는 STA에 있어야합니다. STA은 COM 개체가 항상 UI 스레드에서 조작되어야하며 MFC의 UI 요소와 같이 다른 스레드로 전달 될 수 없음을 의미합니다. 그러나 프로그램에 여전히 많은 스레드가있을 수 있습니다.

MTA- 프로그램의 모든 스레드에서 COM 개체를 조작 할 수 있습니다.


13
"STA는 COM 객체가 항상 UI 스레드에서 조작되어야 함을 의미합니다."이것이 정확히 맞다고 생각하지는 않습니다. "UI"스레드에있을 필요는 없습니다. 메시지를 사용하여 통화가 동기화 되었기 때문에 메시지가 표시됩니다. UI 스레드는 일반적으로 이러한 요구 사항을 충족하지만 이것이 유일한 가능성은 아닙니다.
Brian ONeil

12

내가 이해 한 것처럼 '아파트'는 멀티 스레딩 문제로부터 COM 개체를 보호하는 데 사용됩니다.

COM 객체가 스레드로부터 안전하지 않은 경우 STA 객체로 선언해야합니다. 그런 다음 스레드를 생성 한 스레드 만 액세스 할 수 있습니다. 작성 스레드는 자신을 STA 스레드로 선언해야합니다. 후드 아래에서 스레드는 STA 정보를 TLS (Thread Local Storage)에 저장합니다. 우리는 스레드가 STA 아파트에 들어올 때이 동작을 호출합니다. 다른 스레드가이 COM 개체에 액세스하려면 생성 스레드에 대한 액세스를 마샬링해야합니다. 기본적으로 작성 스레드는 메시지 메커니즘을 사용하여 인바운드 호출을 처리합니다.

COM 개체가 스레드로부터 안전하면 MTA 개체로 선언해야합니다. MTA 개체는 멀티 스레드로 액세스 할 수 있습니다.


4

COM 개체 dll을 호출하는 코드 (예 : 독점 데이터 파일을 읽는 등)는 사용자 인터페이스에서 잘 작동하지만 서비스에서 신비하게 중단 될 수 있습니다. 그 이유는 .Net 2.0부터 사용자 인터페이스는 STA (스레드 세이프)이고 서비스는 MTA (이전 서비스는 STA라고 가정)를 가정하기 때문입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.