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

--
_______________________________________________
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply via email to