//
// Thread class 정의 예제
//
unit RainbowThread;
interface
uses
Classes, SysUtils, ExtCtrls;
type
TRainbowThread = class(TThread)
private
{ Private declarations }
FShape : TShape;
protected
procedure Execute; override;
public
Constructor Create(Shape:TShape);
end;
implementation
{ TRainbowThread }
procedure TRainbowThread.Execute;
begin
Repeat
FShape.Brush.Color:=
Round(Random(256)) shl 16 +
Round(Random(256)) shl 8 +
Round(Random(256));
Sleep(200);
Until Terminated = True; //=====> Terminated 변수의 검사로 진행여부를 결정하도록 처리 한다
end;
Constructor TRainbowThread.Create(Shape:TShape);
Begin
FShape:= Shape; //=====> 초기화 처리는 Inherited Create() 함수 보다 먼저 기입 한다
Inherited Create(True);
End;
end.
//--------------------------------------------------//
// 사용법 1
//--------------------------------------------------//
// 생성 부분
// 전달인자가 True 일때는 Resume 호출로 실행 시켜야 한다
Thread1:= Thread.Create( True );
// 재개
Thread1.Resume;
// 일시 중지
Thread1.Suspend;
// 실행 종료
Thread1.Terminate;
// 실행 종료 대기
Thread1.WaitFor;
// 제거 부분
Thread1.Free; // 또는 FreeAndNil( Thread1 );
--< 주의 >-----------------------------------------
Resume 을 호출하지 않은 상태에서
Suspend를 호출하면 프로그램에 문제가 생겨서
프로그램이 정지 한다
//--------------------------------------------------//
// 사용법 2
//--------------------------------------------------//
// 생성 부분
// 전달인자가 False 이면 바로 실행 한다
// 전달인자가 False 일때 Suspend 함수를 호출하면
// 프로그램에 문제가 생겨서 프로그램이 정지 한다
Thread1:= Thread.Create( False );
// 제거 부분
Thread1.Free; // 또는 FreeAndNil( Thread1 );
//--------------------------------------------------//
// 사용법 3
//--------------------------------------------------//
// 생성 부분
// 전달인자는 실행 시작 여부
// True = Resume 함수 호출로 시작
// False = 바로 시작
Thread1:= Thread.Create( True );
// 실행 종료 되면 자동 제거
Thread1.FreeOnTerminate := True;
// 실행 종료
Thread1.Terminate;
// --< 주의 >---------------------------------------------
// FreeOnTerminate := True; 로 지정한 후에는
// Suspend 또는 Free 함수를 호출하면
// 프로그램에 문제가 생겨서 프로그램이 정지 한다
Delphi Multithreading
When you need to perform background operations or any processing not strictly related to the user interface, you can follow the technically most correct approach: spawn a separate thread of execution within the process. Multithreading programming might seem like an obscure topic, but it really isn't that complex, even if you must consider it with care. It is worth knowing at least the basics of multithreading, because in the world of sockets and Internet programming, there is little you can do without threads.
Delphi's RTL library provides a TThread class that will let you create and control threads. You will never use the TThread class directly, because it is an abstract class—a class with a virtual abstract method. To use threads, you always subclass TThread and use the features of this base class.
The TThread class has a constructor with a single parameter (CreateSuspended) that lets you choose whether to start the thread immediately or suspend it until later. If the thread object starts automatically, or when it is resumed, it will run its Execute method until it is done. The class provides a protected interface, which includes the two key methods for your thread subclasses:
procedure Execute; virtual; abstract; procedure Synchronize(Method: TThreadMethod);
The Execute method, declared as a virtual abstract procedure, must be redefined by each thread class. It contains the thread's main code—the code you would typically place in a thread function when using the system functions.
The Synchronize method is used to avoid concurrent access to VCL components. The VCL code runs inside the program's main thread, and you need to synchronize access to VCL to avoid re-entry problems (errors from re-entering a function before a previous call is completed) and concurrent access to shared resources. The only parameter of Synchronize is a method that accepts no parameters, typically a method of the same thread class. Because you cannot pass parameters to this method, it is common to save some values within the data of the thread object in the Execute method and use those values in the synchronized methods.
Note | Delphi 7 includes two new versions of Synchronize that allow you to synchronize a method with the main thread without calling it from the thread object. Both the new overloaded Synchronize andStaticSynchronize are class methods of TThread and require a thread as parameter. |
Another way to avoid conflicts is to use the synchronization techniques offered by the operating system. The SyncObjs unit defines a few VCL classes for some of these low-level synchronization objects, such as events (with the TEvent class and the TSingleEvent class) and critical sections (with the TCriticalSection class). (Synchronization events should not be confused with Delphi events, as the two concepts are unrelated.)
An Example of Threading
For an example of a thread, you can refer again to the BackTask example. This example spawns a secondary thread for computing the sum of the prime numbers. The thread class has the typical Executemethod, an initial value passed in a public property (Max), and two internal values (FTotal and FPosition) used to synchronize the output in the ShowTotal and UpdateProgress methods. The following is the complete class declaration for the custom thread object:
type TPrimeAdder = class(TThread) private FMax, FTotal, FPosition: Integer; protected procedure Execute; override; procedure ShowTotal; procedure UpdateProgress; public property Max: Integer read FMax write FMax; end;
The Execute method is very similar to the code used for the buttons in the BackTask example listed earlier. The only difference is in the final call to Synchronize, as you can see in the following two fragments:
procedure TPrimeAdder.Execute; var I, Tot: Integer; begin Tot := 0; for I := 1 to FMax do begin if IsPrime (I) then Tot := Tot + I; if I mod (fMax div 100) = 0 then begin FPosition := I * 100 div fMax; Synchronize(UpdateProgress); end; FTotal := Tot; Synchronize(ShowTotal); end; procedure TPrimeAdder.ShowTotal; begin ShowMessage ('Thread: ' + IntToStr (FTotal)); end; procedure TPrimeAdder.UpdateProgress; begin Form1.ProgressBar1.Position := fPosition; end;
The thread object is created when a button is clicked and is automatically destroyed as soon as its Execute method is completed:
procedure TForm1.Button3Click(Sender: TObject); var AdderThread: TPrimeAdder; begin AdderThread := TPrimeAdder.Create (True); AdderThread.Max := Max; AdderThread.FreeOnTerminate := True; AdderThread.Resume; end;
'Delphi, RadStudio' 카테고리의 다른 글
[개발/델파이] MD5 - delphi에서 간단히 다루기 (0) | 2012.10.29 |
---|---|
[개발/delphi] 델파이 TChart 스크롤 기능 구현 (0) | 2012.09.23 |
[개발/delphi] 미래 자동차, 공기로 달리는 자동차 (0) | 2012.08.16 |
[개발/delphi] Windows 7에서 델파이 도움말 사용하기 (0) | 2012.08.12 |
[개발/delphi] 컴포넌트 델파이 6, 7으로 업그레이드 시 dsgnintf 에러 해결하기 (0) | 2012.08.11 |
댓글