Microsoft Windows에서 관리되는 스레딩 및 관리되지 않는 스레딩
업데이트: 2007년 11월
모든 스레드의 관리는 Thread 클래스를 통해 수행되며, 여기에는 공용 언어 런타임에서 만들어진 스레드와 관리되는 환경으로 들어가 코드를 실행하고 런타임 외부에서 만들어진 스레드도 포함됩니다. 관리되는 실행 환경 내에서 이전에 코드를 실행했던 프로세스의 모든 스레드를 런타임에서 모니터링하며 다른 스레드는 추적하지 않습니다. 런타임은 COM 개체와 같은 관리되는 개체를 관리되지 않는 환경에 노출하므로, 스레드는COM interop, COM DllGetClassObject() 함수 및 플랫폼 호출을 통해 관리되는 실행 환경으로 들어갈 수 있습니다.
관리되지 않는 스레드가 COM 호출 가능 래퍼 등을 통해 런타임으로 들어가면 시스템에서는 내부 관리되는 Thread 개체를 찾기 위해 해당 스레드의 스레드 로컬 저장소를 검사합니다. Thread 개체가 있으면 런타임에서 이미 해당 스레드를 인식하고 있는 것입니다. 하지만 시스템에서 개체를 찾지 못하면 런타임에서 새 Thread 개체를 빌드하여 해당 스레드의 스레드 로컬 저장소에 설치합니다.
관리되는 스레딩에서 Thread.GetHashCode는 안정적인 관리되는 스레드 ID이며, 해당 값을 가져온 응용 프로그램 도메인에 상관없이 스레드의 수명 기간 동안 다른 스레드의 값과 충돌하지 않습니다.
참고: |
---|
관리되지 않는 호스트는 관리되는 스레드와 관리되지 않는 스레드 간의 관계를 제어할 수 있으므로 운영 체제 ThreadId는 관리되는 스레드에 대해 고정 관계를 갖지 않습니다. 특히 복잡한 호스트에서는 파이버 API를 사용하여 같은 운영 체제 스레드에 대해 여러 관리되는 스레드의 일정을 세우거나 다른 운영 체제 스레드 간에 관리되는 스레드를 이동할 수 있습니다. |
Win32 스레딩 및 관리되는 스레딩 매핑
다음 표에서는 Win32 스레딩 요소를 런타임 스레딩에 매핑합니다. 이러한 매핑이 동일한 기능을 나타내지는 않습니다. 예를 들어, TerminateThread는 finally 절을 실행하거나, 리소스를 해제하지 않으며, 사용을 금지할 수도 없습니다. 그러나 Thread.Abort는 모든 롤백 코드를 실행하고, 모든 리소스를 해제하며, ResetAbort를 통해 사용을 금지할 수 있습니다. 기능에 대한 자세한 내용은 설명서를 참조하십시오.
Win32 |
공용 언어 런타임 |
---|---|
CreateThread |
Thread와 ThreadStart의 조합 |
TerminateThread |
|
SuspendThread |
|
ResumeThread |
|
Sleep |
|
스레드 핸들의 WaitForSingleObject |
|
ExitThread |
해당하는 스레딩이 없습니다. |
GetCurrentThread |
|
SetThreadPriority |
|
해당 사항 없음 |
|
해당 사항 없음 |
|
CoInitializeEx(OLE32.DLL)와 비슷함 |
관리되는 스레드 및 COM 아파트
관리되는 스레드에 단일 스레드나 다중 스레드 아파트를 호스팅할 것을 표시할 수 있습니다. Thread 클래스의 GetApartmentState, SetApartmentState 및 TrySetApartmentState 메서드는 스레드의 아파트 상태를 반환 및 할당합니다. 상태가 설정되지 않은 경우 GetApartmentState는 ApartmentState.Unknown을 반환합니다.
참고: |
---|
.NET Framework 버전 1.0 및 1.1에서는 ApartmentState 속성을 사용하여 아파트 상태를 가져오거나 설정합니다. |
이 속성은 스레드가 ThreadState.Unstarted 상태일 때만 설정할 수 있으며 스레드에 대해 오직 한 번만 설정할 수 있습니다.
아파트 상태가 스레드가 시작하기 전에 설정된 경우 스레드가 MTA(다중 스레드 아파트)로 초기화됩니다. ThreadPool에서 제어하는 모든 스레드와 종료자 스레드는 MTA입니다.
중요: |
---|
응용 프로그램 시작 코드의 경우 아파트 상태를 제어할 수 있는 방법은 MTAThreadAttribute 또는 STAThreadAttribute를 진입점 프로시저에 적용하는 방법뿐입니다. .NET Framework 버전 1.0 및 1.1에서는 ApartmentState 속성을 코드의 첫 줄로 설정할 수 있습니다. 이 설정은 .NET Framework 버전 2.0에서는 사용할 수 없습니다. |
COM에 노출된 관리되는 개체는 자유 스레드된 마샬러를 집계하는 것처럼 동작합니다. 즉, 모든 COM 아파트에서 자유 스레드된 방식으로 해당 개체를 호출할 수 있습니다. ServicedComponent에서 파생된 개체는 관리되는 개체 중 유일하게 자유 스레드된 동작을 보이지 않습니다.
관리되는 환경에서 컨텍스트와 컨텍스트 바인딩된 관리되는 인스턴스를 사용하지 않으면 SynchronizationAttribute이 지원되지 않습니다. EnterpriseServices를 사용할 경우 개체가 ServicedComponent(ContextBoundObject에서 파생됨)에서 파생되어야 합니다.
관리 코드에서 COM 개체를 호출하는 경우 항상 COM 규칙을 따릅니다. 즉, OLE32에서 지정한 COM+ 1.0 컨텍스트 래퍼와 COM 아파트 프록시를 통해 호출합니다.
차단 문제
비관리 코드의 스레드를 차단하는 운영 체제에 관리되지 않는 호출을 스레드에서 보내면 런타임에서 Thread.Interrupt이나 Thread.Abort에 대한 스레드를 제어하지 않게 됩니다. Thread.Abort의 경우 런타임에서 스레드에 Abort 표시를 하고 관리 코드를 다시 입력할 때 이를 제어합니다. 관리되지 않는 차단보다는 관리되는 차단을 사용하는 것이 더 좋습니다. WaitHandle.WaitOne,WaitHandle.WaitAny, WaitHandle.WaitAll, Monitor.Enter, Monitor.TryEnter, Thread.Join, GC.WaitForPendingFinalizers 등은 모두 Thread.Interrupt 및 Thread.Abort에 응답합니다. 또한 스레드가 단일 스레드 아파트에 있는 경우, 스레드가 차단되는 동안 모든 관리되는 블로킹 작업은 아파트의 메시지를 제대로 펌프하게 됩니다.