The content of this article is taken from the network and re-organized, it is only convenient to learn and consult. All code is tested in person and DELPHI7 under test is valid. Pictures are made for themselves.
Multithreading should be the basic skills of programmers, but this foundation I have never learned, so it just seems to be some, understand the times, actually I do not know.
The beginning should be a voluminous text, but I still advocate to do it first, in the attempt to understand.
Try this first:
procedureTform1.button1click (Sender:tobject);
var
i: integer;
Span class= "Pas__keyword" > begin
for i := 0 to 500000 < Span class= "Pas__keyword" > do
begin
canvas.textout ( 10, 10, inttostr (i);
end ;
end ; &NBSP
When the above program runs, our form is basically "dead", you can try to drag the form while you are running the program ...
Delphi provides us with an easy way (application.processmessages) to solve this problem:
procedureTform1.button1click (Sender:tobject);
var
I:integer;
begin
For i: = 0 to 500000 do
begin
Canvas.textout (Ten, inttostr (i));
Application.processmessages;
End;
End;
This application.processmessages; Typically used in a more time-consuming loop, it checks for and processes other messages in the message queue first.
But this is not a multi-threaded, for example: running when you drag the form, the loop will pause ...
Before using multithreading, let's start by simply modifying the program:
functionMyfun:integer;
var
I:integer;
begin
forI: =0 to500000 Do
begin
Form1.Canvas.Lock;
Form1.Canvas.TextOut (Ten, inttostr (i));
Form1.Canvas.Unlock;
End;
Result: = 0;
End;
procedure Tform1.button1click (Sender:tobject);
begin
Myfun;
End;
To count the changes in the above program:
1, first of all this is not multi-threaded, but also let the form false "dead" a while;
2, write the execution code in a function, but this function does not belong to the method of TForm1, so the use of Canvas is must be crowned name (FORM1);
3, since it is a function, (whether or not necessary) should have a return value;
4, used 500,001 times Lock and Unlock.
Canvas.lock like to say: canvas (drawing surface) is busy, others want to use canvas and so on;
Canvas.unlock: It's done, unlock!
It's a good habit to use Lock and Unlock in Canvas, but it doesn't matter if you don't use multithreading, but it's not guaranteed that the program will be extended to multi-threaded; We are now learning multi-threading, which of course should be used.
There are two ways to use multithreading in Delphi: Calling the API, using the TThread class; The code for using the API is much simpler.
functionMyfun (p:pointer): Integer; stdcall;
var
I:integer;
begin
forI: =0 to500000 Do
begin
Form1.Canvas.Lock;
Form1.Canvas.TextOut (10,IntToStr (i));
Form1.Canvas.Unlock;
End;
Result: = 0;
End;
procedure Tform1.button1click (Sender:tobject);
var
Id:thandle;
begin
CreateThread (nil, 0, @MyFun, nil, 0, ID);
End;
Code Analysis:
CreateThread a thread, calculate the original main thread, so that the program has two threads, is the standard multithreading;
CreateThread The third argument is the function pointer, which executes immediately after the new thread is established, and the execution of the function completes and the system destroys the thread to end the multithreaded story.
CreateThread the function to be used is system-level, cannot be a method of a class (for example: TForm1), and has strict formatting (parameters, return value) requirements, whether you need to be in the form of a temporary or not;
Because it is a system-level call, but also the stdcall, stdcall is the coordination parameter order, although there is only one parameter is not in order, but this is the practice of using system functions.
CreateThread also needs a var parameter to accept the ID of the new thread, although it is temporarily useless, but this is also the format; Other parameters later.
This is the simplest multi-thread that comes out, let's use the TThread class to implement a
type
Tmythread =class(TThread)
protected
procedureExecute; Override
End;
procedureTmythread.execute;
var
I:integer;
begin
Freeonterminate: = True;{This allows the thread to be freed after execution is complete}
forI: =0 to 500000 do
begin
Form1.Canvas.Lock;
form1.canvas.textout ( 10, 10, inttostr (i))
Form1.Canvas.Unlock;
end ;
end ;
procedure tform1.button1click (sender: tobject);
begin
tmythread.create (False);
end ;
The TThread class has an abstract method (Execute) and is therefore an abstract class, and the abstract class can only be inherited and inherited as Tmythread.
Inheriting TThread is basically implementing an abstract method of execute (writing our code inside), and when our tmythread is instantiated, the code in the Execute method is executed first.
We generally instantiate this as usual:
procedure TForm1.Button1Click(Sender: TObject);
var
MyThread: TMyThread;
begin
MyThread := TMyThread.Create(False);
end;
Because the MyThread variable is useless here (and the compiler has hints), it is better to write Tmythread.create (False) directly;
We can also easily solve a problem if: Tmythread.create (True)?
This will not invoke execute immediately after the thread is established, and can then execute the thread with the Resume method when needed, such as:
procedureTform1.button1click (Sender:tobject);
var
Mythread:tmythread;
begin
MyThread: = Tmythread.create (True);
Mythread.resume;
End;
Can be simplified to:
procedure Tform1.button1click (Sender:tobject);
begin
With tmythread.create (True) do Resume;
end;
Delphi's Multi-threading program