델파이의 스레드 클래스
랩터[멘탈스튜디오]
http://mental.mentu.com
제삼
생성자에 대해 이야기한 후 소멸자를 살펴보겠습니다.
소멸자 TThread.Destroy;
시작하다
(FThreadID <> 0)이고 FFinished가 아닌 경우
시작하다
끝내다;
FCreateSuspended라면
재개하다;
잠깐만;
끝;
FHandle <> 0이면 CloseHandle(FHandle);
상속됨 파괴;
FFatalException.Free;
스레드 제거;
끝;
스레드 개체를 해제하기 전에 먼저 스레드가 여전히 실행 중인지 확인합니다. 스레드가 여전히 실행 중인 경우(스레드 ID가 0이 아니고 스레드 종료 플래그가 설정되지 않은 경우) Terminate 프로세스를 호출하여 스레드를 종료합니다. Terminate 프로세스는 다음 코드와 같이 스레드 클래스의 Terminate 플래그를 설정합니다.
절차 TThread.Terminate;
시작하다
F종료됨 := True;
끝;
따라서 스레드는 즉시 종료되는 것이 아니라 정상적으로 종료될 때까지 계속 실행되어야 합니다.
약간의 여담: 많은 사람들이 스레드를 "즉시" 종료하는 방법을 묻습니다(물론 TThread로 생성된 스레드를 참조함). 물론 작동하지 않습니다! 스레드를 종료하는 유일한 방법은 Execute 메서드가 실행을 완료하도록 하는 것입니다. 따라서 일반적으로 스레드를 최대한 빨리 종료하려면 짧은 시간 내에 Execute 메서드의 Terminating 플래그를 지속적으로 확인해야 합니다. 시간 내에 나갈 수 있다는 것. 이는 스레드 코드를 디자인할 때 매우 중요한 원칙입니다!
물론, 스레드를 "즉시" 종료할 수 있어야 한다면 TThread 클래스는 좋은 선택이 아닙니다. API를 사용하여 스레드를 강제로 종료하면 TThread 스레드 객체가 결국 올바르게 해제되지 않고, 접근 위반은 객체가 소멸될 때 발생합니다. 이 경우 API 또는 RTL 함수만 사용하여 스레드를 생성할 수 있습니다.
스레드가 시작 일시 중지 상태인 경우 스레드를 실행 상태로 전환한 다음 WaitFor를 호출하여 실행을 계속하기 전에 스레드가 끝날 때까지 기다리는 기능입니다. WaitFor의 구현은 나중에 설명하겠습니다.
스레드가 종료된 후 스레드 핸들(핸들은 일반적인 스레드 생성 시 존재함)을 닫고 운영 체제에서 생성된 스레드 개체를 해제합니다.
그런 다음 TObject.Destroy를 호출하여 이 객체를 해제하고 포착된 예외 객체를 해제한 다음 마지막으로 RemoveThread를 호출하여 프로세스의 스레드 수를 줄입니다.
일시 중지/재개 및 스레드 우선 순위 설정과 관련된 다른 측면은 이 문서의 초점이 아니므로 다시 논의하지 않습니다. 아래에서 논의할 내용은 이 문서의 다른 두 가지 초점인 동기화 및 대기에 대한 것입니다.
그러나 이 두 가지 기능을 도입하기 전에 이벤트와 중요 섹션이라는 두 가지 다른 스레드 동기화 기술을 도입해야 합니다.
이벤트는 델파이의 이벤트와 다릅니다. 본질적으로 Event는 전역 부울 변수와 동일합니다. 여기에는 True 또는 False로 설정하는 것과 동일한 Set 및 Reset의 두 가지 할당 작업이 있습니다. 그리고 그 값의 확인은 WaitFor 연산을 통해 이루어집니다. Windows 플랫폼에는 SetEvent, ResetEvent, WaitForSingleObject의 세 가지 API 함수가 있습니다(WaitFor 함수를 구현하는 API가 여러 개 있는데 이것이 가장 간단한 API입니다).
이 세 가지는 기본 요소이므로 Event는 일반 부울 변수가 할 수 없는 다중 스레드에서 애플리케이션을 구현할 수 있습니다. Set 및 Reset의 기능은 이전에 언급되었습니다. 이제 WaitFor의 기능에 대해 이야기하겠습니다.
WaitFor의 기능은 Event의 상태가 Set 상태(True와 동일)인지 확인하는 것이며, 그렇지 않은 경우에는 대기 기간 동안 Set 상태로 변경될 때까지 기다립니다. WaitFor를 호출하는 스레드가 일시 중단된 상태입니다. 또한, WaitFor에는 타임아웃 설정을 위한 파라미터가 있습니다. 이 파라미터가 0이면 기다리지 않고 즉시 Event 상태를 반환합니다. INFINITE인 경우에는 Set 상태가 발생할 때까지 무한히 대기합니다. 해당 시간(밀리초) 동안 기다린 다음 이벤트 상태를 반환합니다.
이벤트가 Reset 상태에서 Set 상태로 전환되면 WaitFor 이벤트로 인해 일시 중단된 다른 스레드를 깨웁니다. 이것이 이벤트라고 불리는 이유입니다. 소위 "이벤트"는 "상태 전환"을 의미합니다. 이 "상태 전환" 정보는 이벤트를 통해 스레드 간에 전달될 수 있습니다.
물론 WaitFor가 부울 값을 확인하는 코드 루프로 대체되는 한 보호된(아래 중요 섹션 소개 참조) 부울 변수를 사용하여 유사한 기능을 구현할 수도 있습니다. 기능적으로는 전혀 문제가 없지만, 실제로 사용해보면 이러한 대기는 CPU 자원을 많이 차지하고, 시스템 성능을 저하시키며, 다른 스레드의 실행 속도에 영향을 미치므로 비경제적이며 때로는 가능할 수도 있다는 것을 알게 될 것입니다. 문제. 따라서 이런 방식으로 사용하는 것은 권장되지 않습니다.
(계속 예정)