Here's a more complete tutorial to read.
Threads are a great way to do a large amount of processing in your program while allowing the visual part of your program to remain responsive. If you can split up the processing into several threads you can take advantage of modern processors multi core capability and complete a job in a fraction of the time.
Lazarus programs can use threads in GUI and Console programs. If you use threading in your program you should define the compiler option
-dUseCThreads. This can be done in Project->Options->Compiler Options->Other - Custom Options. This does nothing under Windows but on any *nix it includes a needed threadmanager. If your program crashes with the first use of thread.Start; then this is probably your problem.
Now that your program is thread enabled here's some basic information about threads. You must subclass the
TThreadtype and make your own thread type and override the
Executemethod is never called directly in your program. It is the method the thread will run on it's own when it is started. If you are using
MyThread.Executethen you are making a mistake.
Here's a basic example of a new thread type
TFooThread = class(TThread)
procedure Execute; override;
// do stuff
To create an instance of your thread you can use
FooThread := TFooThread.Create(True);
Truecreates the thread in suspended state, meaning the OS thread is created but not yet run. If you use
Falsethen the thread begins and
Executeis called immediately. You can of course make your own constructor with whatever parameters you need and use
To start a thread you should use
FooThread.Resumeis deprecated as well as
.Suspendwhich is not reliable on *nix's and can cause your program to hang.
Now your thread is running and working and making your life easier. Your program is snappier and you decide that you need to make your program display the progress your thread is making processing some data.
So in TFooThread.Execute you add Form1.ProgressBar1.Position := SomeValue.
Bad idea. It may work or your program could immediately crash or it might cause some other harder to find error that happens later. Never ever do this.
The reason this is so bad is because the GUI part of your program is run in a separate thread (duh!) and has it's own memory area. Changing the memory in one thread from another needs to be coordinated carefully. You should never change a LCL control value from a thread other than the main process.
A way to update the main thread from another thread is the
Syncronizemethod, which is called within a created thread, causes the thread to pause and wait for the main thread to call a procedure. Also see CritialSections from the link at the beginning of this article
When your thread terminates you should assume that any code in it's destructor may be called a thread other than your main process thread, especially if you set
True. If you assign a handler for the OnTerminate property then that procedure will be run in the main thread.
After all the code in the
Executemethod is run your thread cannot be restarted. You will have to free and create another instance of the thread type you need. It's common to include
while not Terminated do begin ... endaround the code inside the
Executemethod in order to use a thread multiple times without having to recreate it.
Most of the basic stuff I have run into is now covered. Go code, or read some more: Threading Tutorial on the Wiki