Description |
The BeginThread function starts a separate 'thread' of code execution, independent of the main code.
You can have more than one thread - each thread is another, independent variation on the main line of code execution.
When calling a BeginThread function, you are creating a new thread which executes the specified ThreadFunc function. This is a function with Param as its singles Pointer argument. The thread runs until this function ends.
When the thread is created, it returns a thread id in the returned integer. When the thread returns, you should call the CloseThread Windows function to free up resources.
Each thread has the same access to the Unit data as the main line of execution. Much care must be taken when accessing data shared between threads.
To provide data unique variable instances to each thread, use a ThreadVar definition in the Unit, as in the example.
You can pass data to each thread via the Param pointer, as in the example.
The SecurityAttr attributes, StackSize and the CreateFlags are beyond the scope of this article. It is suffice for beginners to set these fields to nil and 0 as appropriate.
|
|
Notes |
The TThread class provides an alternate method of thread implementation.
Threading is a complex topic - this topic merely touches the surface. Matters such as synchronisation of threads, and concurrent data access control are beyond the scope of Smart Pascal.
|
|
Related commands |
EndThread |
|
Terminates a thread with an exit code |
IsMultiThread |
|
Returns true if the code is running multiple threads |
ThreadVar |
|
Defines variables that are given separate instances per thread |
|
|
|
Example code : A simple example that displays multiple dialogs |
// Full Unit code. // ----------------------------------------------------------- // You must store this code in a unit called Unit1 with a form // called Form1 that has an OnCreate event called FormCreate.
unit Unit1;
interface
uses
Forms, Dialogs, Windows, SysUtils;
type
TMsgRecord = record
thread : Integer;
msg : string[30];
end;
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
end;
var
Form1: TForm1;
Implementation
{$R *.dfm} // Include form definitions
ThreadVar // We must allow each thread its own instances // of the passed record variable
msgPtr : ^TMsgRecord;
// Private thread procedure to show a string
function ShowMsg(Parameter : Pointer) : Integer;
begin // Set up a 0 return value
Result := 0;
// Map the pointer to the passed data // Note that each thread has a separate copy of msgPtr
msgPtr := Parameter;
// Display this message
ShowMessagePos('Thread '+IntToStr(msgPtr.thread)+' '+msgPtr.msg,
200*msgPtr.thread, 100);
// End the thread
EndThread(0);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
id1, id2 : LongWord;
thread1, thread2 : Integer;
msg1, msg2 : TMsgRecord;
begin // set up our display messages
msg1.thread := 1;
msg1.msg := 'Hello World';
msg2.thread := 2;
msg2.msg := 'Goodbye World';
// Start the first thread running asking for users first name
thread1 := BeginThread(nil,
0,
Addr(ShowMsg),
Addr(msg1),
0,
id1);
// And also ask for the surname
thread2 := BeginThread(nil,
0,
Addr(ShowMsg),
Addr(msg2),
0,
id2);
// Ensure that the threads are only closed when all done
ShowMessagePos('Press this when other dialogs finished.', 200, 300);
// Finally, tidy up by closing the threads
CloseHandle(thread1);
CloseHandle(thread2);
end;
end.
|
Three dialogs are displayed:
Thread 1 Hello World
Thread 2 Goodbye World
Press this when other dialogs finished.
|
|