델파이의 스레드 클래스
랩터[멘탈스튜디오]
http://mental.mentu.com
(하나)
델파이에는 멀티 스레드 프로그래밍을 구현하는 데 사용되는 스레드 클래스 TThread가 있습니다. 대부분의 델파이 책에서는 이에 대해 언급하지만 기본적으로 TThread 클래스의 여러 멤버에 대해 간략하게 소개한 다음 실행 기능을 설명합니다. 동기화가 완료되었습니다. 그러나 이것이 멀티스레드 프로그래밍의 전부는 아닙니다. 이 글을 쓰는 목적은 이를 보완하는 것입니다.
스레드는 본질적으로 프로세스에서 동시에 실행되는 코드 조각입니다. 프로세스에는 소위 메인 스레드라고 하는 스레드가 하나 이상 있습니다. 동시에 여러 개의 하위 스레드가 있을 수도 있습니다. 하나의 프로세스에서 둘 이상의 스레드가 사용되는 경우를 "멀티스레딩"이라고 합니다.
그렇다면 소위 "코드 조각"은 어떻게 정의됩니까? 실제로 이는 (Delphi의 경우) 함수 또는 프로세스입니다.
Windows API를 사용하여 스레드를 생성하는 경우 다음과 같이 정의되는 CreateThread라는 API 함수를 통해 구현됩니다.
CreateThread(를 처리합니다.
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWord dwStack 크기,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lp매개변수,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
매개변수는 이름에서 알 수 있듯이 스레드 속성(NT에서는 스레드 보안 속성을 설정하는 데 사용되며 9X에서는 유효하지 않음), 스택 크기, 시작 주소, 매개변수, 생성 플래그(생성 시 스레드 상태를 설정하는 데 사용됨), 스레드 ID 및 마지막으로 스레드 핸들을 반환합니다. 시작 주소는 스레드 함수의 입구입니다. 스레드 함수가 끝날 때까지 스레드는 종료됩니다.
전체 스레드의 실행 과정은 다음과 같습니다.
CreateThread에는 많은 매개 변수가 있고 Windows API이므로 C 런타임 라이브러리에 일반 스레드 함수가 제공됩니다(이론적으로 스레드를 지원하는 모든 OS에서 사용할 수 있음).
unsigned long _beginthread(void (_USERENTRY *__start)(void *), unsigned __stksize, void *__arg);
Delphi는 동일한 기능을 갖춘 유사한 기능도 제공합니다.
function BeginThread(SecurityAttributes: 포인터; StackSize: LongWord; ThreadFunc: TThreadFunc; 매개변수: 포인터; CreationFlags: LongWord; var ThreadId: LongWord): Integer;
이 세 가지 함수의 기능은 기본적으로 모두 동일합니다. 스레드 함수의 코드를 독립적인 스레드에 넣어 실행합니다. 스레드 함수와 일반 함수의 가장 큰 차이점은 스레드 함수가 시작되자마자 3개의 스레드 시작 함수가 반환된다는 점입니다. 메인 스레드는 계속해서 아래쪽으로 실행되는 반면, 스레드 함수는 독립 스레드에서 실행되는 시간이 얼마나 됩니까? 실행에 걸릴까요? 반환되면 메인 스레드는 신경 쓰지 않고 알지 못합니다.
일반적인 상황에서는 스레드 함수가 반환된 후 스레드가 종료됩니다. 하지만 다른 방법도 있습니다:
윈도우 API:
VOID ExitThread(DWORD dwExitCode);
C 런타임 라이브러리:
void _endthread(void);
델파이 런타임 라이브러리:
PROcedure EndThread(ExitCode: 정수);
필요한 스레드 데이터(상태/속성 등)를 기록하기 위해 OS는 스레드에 대한 내부 개체를 생성합니다. 예를 들어 Windows에서는 핸들이 이 내부 개체의 핸들이므로 이 개체를 해제해야 합니다. 스레드가 끝날 때.
멀티 스레드 프로그래밍은 API나 RTL(런타임 라이브러리)을 사용하여 쉽게 수행할 수 있지만 여전히 더 자세한 처리가 필요합니다. 이러한 이유로 Delphi는 클래스 유닛에서 스레드를 더 잘 캡슐화했습니다. 이것이 바로 VCL 스레드 클래스인 TThread입니다.
이 클래스를 사용하는 것도 매우 간단합니다. 대부분의 Delphi 책에서는 기본 사용법이 다음과 같다고 말합니다. 먼저 TThread에서 자신만의 스레드 클래스를 파생시킨 다음(TThread는 추상 클래스이고 인스턴스를 생성할 수 없기 때문입니다) 그런 다음 Override 추상 메서드를 사용합니다. 스레드에서 실행되는 코드의 일부인 스레드 함수입니다.) 시각적 VCL 개체를 사용해야 하는 경우 동기화 프로세스를 통해 수행해야 합니다. 구체적인 내용은 여기서는 관련 서적을 참조하지 않겠습니다.
이 기사의 다음 내용은 TThread 클래스가 스레드를 캡슐화하는 방법, 즉 TThread 클래스 구현에 대한 심층적인 연구입니다. 진정으로 이해해야만 더 잘 사용할 수 있기 때문입니다.
다음은 DELPHI7의 TThread 클래스 선언입니다(이 문서에서는 Windows 플랫폼에서의 구현에 대해서만 설명하므로 Linux 플랫폼과 관련된 모든 코드는 제거되었습니다).
TThread = 클래스
사적인
FHandle: THandle;
FThreadID: THandle;
FCreateSuspended: 부울;
FTerminating: 부울;
FSuspended: 부울;
FFreeOnTerminate: 부울;
FFinished: 부울;
FReturnValue: 정수;
FOnTerminate: TNotifyEvent;
FSynchronize: TSynchronizeRecord;
FFatalException: TObject;
프로시저 CallOnTerminate;
클래스 프로시저 동기화(ASyncRec: PSynchronizeRecord);
함수 GetPriority: TThreadPriority;
절차 SetPriority(값: TThreadPriority);
절차 SetSuspended(값: Boolean);
보호됨
프로시저 CheckThreadError(ErrCode: Integer);
절차 CheckThreadError(성공: 부울);
프로시저 DoTerminate;
절차 가상 실행;
프로시저 동기화(메소드: TThreadMethod);
속성 ReturnValue: 정수 읽기 FReturnValue 쓰기 FReturnValue;
Terminate 속성: 부울 읽기 FTerminating;
공공의
생성자 Create(CreateSuspended: Boolean);
소멸자 재정의;
절차 AfterConstruction;
절차 이력서;
절차일시중단;
절차 종료;
함수 WaitFor: LongWord;
클래스 프로시저 동기화(AThread: TThread; AMethod: TThreadMethod);
클래스 프로시저 StaticSynchronize(AThread: TThread; AMethod: TThreadMethod);
속성 FatalException: TObject 읽기 FFatalException;
속성 FreeOnTerminate: 부울 읽기 FFreeOnTerminate 쓰기 FFreeOnTerminate;
속성 핸들: THandle은 FHandle을 읽습니다.
속성 우선순위: TThreadPriority 읽기 GetPriority 쓰기 SetPriority;
속성 일시 중단: 부울 읽기 FSuspended 쓰기 SetSuspended;
속성 ThreadID: THandle은 FThreadID를 읽습니다.
속성 OnTerminate: TNotifyEvent 읽기 FOnTerminate 쓰기 FOnTerminate;
끝;
TThread 클래스는 Delphi의 RTL에서 비교적 간단한 클래스이며 클래스 속성은 매우 간단하고 명확합니다. 이 기사에서는 몇 가지 중요한 클래스 멤버 메서드와 유일한 이벤트인 OnTerminate에 대해서만 자세히 분석합니다. .
(계속 예정)