다음을 통해 공유


Windows에서 관리되는 스레딩 및 관리되지 않는 스레딩

공용 언어 런타임에 의해 만들어진 스레드 및 런타임 외부에서 만들어져 코드를 실행하기 위해 관리되는 환경에 들어가는 스레드를 비롯한 모든 스레드는 Thread 클래스를 통해 관리됩니다. 런타임은 해당 프로세스에서 관리되는 실행 환경 내에서 코드를 실행한 적이 있는 모든 스레드를 모니터링하며, 다른 모든 스레드는 추적하지 않습니다. 스레드는 COM interop(런타임이 관리되는 개체를 관리되지 않는 환경에 COM 개체로 노출하므로), COM DllGetClassObject 함수 및 플랫폼 호출을 통해 관리되는 실행 환경에 들어갈 수 있습니다.

관리되지 않는 스레드가 COM 호출 가능 래퍼를 통해 런타임에 들어가면 시스템에서는 해당 스레드의 스레드 로컬 저장소를 확인하여 내부의 관리되는 Thread 개체를 찾습니다. 이 개체를 찾은 경우 런타임이 이미 이 스레드에 대해 알고 있는 것입니다. 그러나 이 개체를 찾을 수 없으면 런타임은 새 Thread 개체를 빌드하여 해당 스레드의 스레드 로컬 저장소에 설치합니다.

관리되는 스레딩에서 Thread.GetHashCode 는 안정적인 관리되는 스레드 ID입니다. 이는 이 값을 가져온 애플리케이션 도메인과 관계없이 스레드 수명 동안 다른 모든 스레드의 값과 충돌하지 않습니다.

Win32 스레딩에서 관리되는 스레딩으로 매핑

다음 테이블에는 Win32 스레딩 요소가 대략적으로 동일한 런타임 요소에 매핑되어 있습니다. 이 매핑은 동일한 기능을 나타내지 않습니다. 예를 들어, TerminateThreadfinally 절을 실행하거나 리소스를 해제하지 않고 방지될 수 없습니다. 그러나 Thread.Abort 는 모든 롤백 코드를 실행하고 모든 리소스를 회수하며 ResetAbort를 사용하여 거부될 수 있습니다. 기능에 대해 가정하기 전에 설명서를 주의해서 읽어야 합니다.

Win32 공용 언어 런타임
CreateThread ThreadThreadStart의 조합
TerminateThread Thread.Abort
SuspendThread Thread.Suspend
ResumeThread Thread.Resume
Sleep Thread.Sleep
스레드 핸들의 WaitForSingleObject Thread.Join
ExitThread 동일한 요소 없음
GetCurrentThread Thread.CurrentThread
SetThreadPriority Thread.Priority
동일한 요소 없음 Thread.Name
동일한 요소 없음 Thread.IsBackground
CoInitializeEx(OLE32.DLL)와 비슷함 Thread.ApartmentState

관리되는 스레드 및 COM 아파트

관리되는 스레드는 단일 스레드 또는 다중 스레드 아파트를 호스트할 것임을 나타내기 위해 표시될 수 있습니다. (COM 스레딩 아키텍처에 대한 자세한 내용은 프로세스, 스레드 및 아파트를 참조하세요.) GetApartmentState 클래스의 SetApartmentState, TrySetApartmentStateThread 메서드는 스레드의 아파트 상태를 반환하고 할당합니다. 상태가 설정되지 않은 경우 GetApartmentStateApartmentState.Unknown을 반환합니다.

이 속성은 스레드가 ThreadState.Unstarted 상태일 때만 설정될 수 있으며, 한 스레드에 대해 한 번만 설정될 수 있습니다.

스레드가 시작되기 전에 아파트 상태가 설정되지 않은 경우 스레드가 MTA(다중 스레드 아파트)로 초기화됩니다. 종료자 스레드 및 ThreadPool 에 의해 제어되는 모든 스레드는 MTA입니다.

Important

애플리케이션 시작 코드의 경우 아파트 상태를 제어하는 유일한 방법은 MTAThreadAttribute 또는 STAThreadAttribute 를 진입점 프로시저에 적용하는 것입니다.

COM에 노출되는 관리되는 개체는 자유 스레드 마샬러를 집계한 것처럼 동작합니다. 즉, 모든 COM 아파트에서 자유 스레드 방식으로 이러한 개체를 호출할 수 있습니다. 이 자유 스레드 동작을 노출하지 않는 관리되는 개체만이 ServicedComponent 또는 StandardOleMarshalObject에서 파생되는 개체입니다.

관리되는 세계에는 컨텍스트 및 컨텍스트 바인딩된 관리되는 인스턴스를 사용하지 않는 한 SynchronizationAttribute에 대한 지원이 없습니다. 엔터프라이즈 서비스를 사용 중인 경우 개체는 ServicedComponent(이 자체는 ContextBoundObject에서 파생됨)에서 파생되어야 합니다.

관리 코드가 COM 개체를 호출할 때는 항상 COM 규칙을 따릅니다. 즉, 관리 코드는 OLE32에서 지시하는 대로 COM 아파트 프록시 및 COM+ 1.0 컨텍스트 래퍼를 통해 호출합니다.

차단 문제

스레드가 비관리 코드에서 스레드를 차단한 운영 체제에 대해 관리되지 않는 호출을 수행할 경우 런타임이 Thread.Interrupt 또는 Thread.Abort에 대해 스레드를 제어하지 못합니다. Thread.Abort의 경우 런타임은 스레드에 Abort를 표시하고 스레드가 관리 코드에 다시 들어가면 스레드를 제어합니다. 관리되지 않는 차단이 아니라 관리되는 차단을 사용하는 것이 좋습니다. WaitHandle.WaitOne,WaitHandle.WaitAny, WaitHandle.WaitAll, Monitor.Enter, Monitor.TryEnter, Thread.Join, GC.WaitForPendingFinalizers 등은 모두 Thread.InterruptThread.Abort에 응답합니다. 또한 스레드가 단일 스레드 아파트에 있는 경우 이러한 모든 관리되는 차단 작업은 스레드가 차단되어 있는 동안 올바르게 아파트에 메시지를 펌핑합니다.

스레드 및 파이버

.NET 스레딩 모델은 파이버를 지원하지 않습니다. 파이버를 사용하여 구현된 관리되지 않는 함수를 호출하면 안 됩니다. 이러한 호출로 인해 .NET 런타임에서 크래시가 발생할 수 있습니다.

참고 항목