[Lazarus] Threads
Sven Barth
pascaldragon at googlemail.com
Fri Mar 23 10:59:12 CET 2012
Am 23.03.2012 10:25, schrieb Antonio Fortuny:
> Le 22/03/2012 16:20, Mattias Gaertner a écrit :
>>
>> Each thread has its own stack.
>>
>> All threads share the same address space and the same heap.
>>
>> Objects (here: class instances) are created on the heap. The heap is
>> thread safe.
>>
>> The data segment is for constants. They are shared.
>>
> Le 22/03/2012 17:10, Michael Schnell a écrit :
>> Besides what the other said a very basic comment.
>>
>> The location where an object is defined (i.e. within a TThread enabled
>> unit) or who created it (the main line code or the thread code) does
>> not matter. The Concept of classes, objects and instances is a matter
>> of memory allocation and pointers and not a concept of program flow.
>> same is absolutely independent. You can use one instance of a class in
>> one thread and another one in another thread. You can create an
>> instance in one thread and call its procedures and properties by
>> another one. (BTW this results in the fact that its very hard to
>> define something like "Thread-safe" for a class).
> Thanks to you all .
> Trying to be as much clear as possible, there are some sentences:
>
> Assuming this few statements (aka my own rules when writing thread's code):
> a. all thread code+data are encapsulated into a TThread object
> b. "Thread safe" means that there is no overlap of data references from
> thread to thread, the main thread inclusive, and that no references are
> passed outside the thread's control from thread to thread (by the means
> of the owner or global vars for instance)
> c. the thread creator does not interfere in any way with the thread's
> data and methods as soon as the thread has been started (Terminated
> execpted of course)
> d. no function neither procedure calls are made to any function or
> procedure defined outside of the thread control (aka self defined methods)
Ok, I hereby assume the above as given.
> Do you all agree on the following asserts:
> 1. All variables in the thread definition (TThread's private, protected
> and public variables) are "Thread safe" BUT are accessible to the thread
> creator
Yes (though the private vars aren't available to the thread creator if
the creator and the definition of your TThread descendant reside in
different units ;) )
> 2. an instance of an object (aka TObject descendant) created into the
> thread's EXECUTE procedure is invisible to all other instances of the
> same object whichever the creator could be (the same thread or other
> threads created with the same thread definition object) and to other
> thread object instances, even when the reference variable of the created
> object is defined into the thread vars (see 1.) provided that all object
> methods do not call any function or procedure outside of the object methods.
If I've understood that correctly: yes
> 3. all variables described in the VAR part of the EXECUTE procedure are
> "Thread safe" (seems obvious)
Yes
> 4. all local variables and constants defined into local Thread object
> methods are "Thread safe" (they are defined into each thread stack for
> the vars and the heap for constants)
It's true for variables. Local constants are defined in a section of the
executable, so if you have writable constants enabled (only then it's a
problem) and you write to these constants then the change will be
reflected in other constants as well. If you don't write to the
constants than they are safe.
> 5. all useful code a thread needs should be encapsultated into a TObject
> descendant and instantiated within the thread's space.
Note necessarily. You can also call global procedures/functions that
don't rely on global state (e.g. IntToStr, etc.). If you want to call
functions/procedures that rely on the state (e.g. some registration
systems for classes) you'll need to synchronize the access.
> 6. all methods defined in the thread's definition, aprat from the
> EXECUTE procedure (obvious !), run into the thread creator space (the
> one which instantiates the thread, aka does something like wThread :=
> TMyThread.Create (False) )
I don't know whether I understood you correctly, but if you have this:
=== example begin ===
type
TTestThread = class(TThread)
protected
procedure Execute; override;
public
procedure DoSomething;
end;
procedure TTestThread.Execute;
begin
DoSomething;
end;
procedure TTestThread.DoSomething;
begin
Writeln('Something');
end;
begin
with TTestThread.Create(True) do begin
FreeOnTerminate := True;
Start;
end;
end.
=== example end ===
Then (to my understandment of your assertion) your assertion is wrong,
because DoSomething is (although it is public) only called in context of
Execute (Note: Not that you should make such a method public if you
don't need to, but this is merely an example).
Regards,
Sven
More information about the Lazarus
mailing list